LS-DOS 6.3.1 - LOWCORE 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_2011 at nemesis.lonestar.org]
MISOSYS EDAS-4.3 04/11/99 19:02:04 LOWCORE - LS-DOS 6.2         Page 00001 

              00001 ;LOWCORE/ASM - Low Memory Assignments
0000          00003 @MOD2   EQU     00              ;Set MOD2 false
FFFF          00004 @MOD4   EQU     -1              ;Set MOD4 true
0000          00005 *GET    BUILDVER/ASM:3
              00006 ;
              00007 ;       Buildver/asm is a bit of a kludge since not all utilities can load
              00008 ;       equates from LDOS60 and still compile.  LOWCORE and everybody else
              00009 ;       relies on this setting, and it eventually ends up in LDOS60/EQU
              00010 ;       for programs that can use that.
              00011 ;
FFFF          00012 @BLD631         EQU     -1      ;<631>Build 631 distribution (LEVEL 1B)
              00013 ;       These switches activate patches made since the 1B release.
              00014 ;       It is important that all earlier patches be enabled when a higher
              00015 ;       patch is enabled.
              00016 ;       Patches C thru F were published in TMQ IV.iv, page 32 (NOTE: the
              00017 ;       patch addresses listed for SPOOL in SPOOL1/FIX are 19H high.)
FFFF          00018 @BLD631C        EQU     -1      ;<631>Apply 1C patches (SETKI)
FFFF          00019 @BLD631D        EQU     -1      ;<631>Apply 1D patches (DIR)
FFFF          00020 @BLD631E        EQU     -1      ;<631>Apply 1E patches (DIR & MEMDISK/DCT)
FFFF          00021 @BLD631F        EQU     -1      ;<631>Apply 1F patches (SPOOL)
              00022 ;       Patches G and H were published in TMQ V.i, pages 10 and 18/19.
FFFF          00023 @BLD631G        EQU     -1      ;<631>Apply 1G patches (//KEYIN,DIR,DO *)
FFFF          00024 @BLD631H        EQU     -1      ;<631>Apply 1H patches (MEMORY)
              00025 ;
              00026 ;End of BUILDVER/ASM
              00027 ;
              00028 ;       LDOS 6.x Low Core RAM storage assignments
              00029 ;       Copyright (C) 1982 by Logical Systems, Inc.
              00030 ;
              00031 ;       Define switches for international or domestic
              00032 ;
0000          00033 @GERMAN EQU     0
0000          00034 @FRENCH EQU     0
              00035         IF      @GERMAN.AND.@FRENCH
              00036         ERR     'Can''t do both French and German'
              00037         ENDIF
              00038         IF      @GERMAN.OR.@FRENCH
              00039 @INTL   EQU     -1
              00040 @USA    EQU     00
              00041 @HZ50   EQU     -1
              00042         ELSE
0000          00043 @INTL   EQU     00
FFFF          00044 @USA    EQU     -1
0000          00045 @HZ50   EQU     00
              00046         ENDIF
              00047 ;
0000          00048 START$  EQU     0
              00049 ;
              00050 ;       These EQUs are detailed in SYSRES
              00051 ;
000E          00052 FDDINT$ EQU     0EH
001B          00053 PDRV$   EQU     1BH
002B          00054 TIMSL$  EQU     2BH
002C          00055 TIMER$  EQU     2CH
002D          00056 TIME$   EQU     TIMER$+1
0033          00057 DATE$   EQU     33H
003E          00058 INTVC$  EQU     3EH
006A          00059 FLGTAB$ EQU     6AH
006C          00060 CFLAG$  EQU     FLGTAB$+'C'-'A'
006D          00061 DFLAG$  EQU     FLGTAB$+'D'-'A'
0072          00062 IFLAG$  EQU     FLGTAB$+'I'-'A'
0074          00063 KFLAG$  EQU     FLGTAB$+'K'-'A'
0076          00064 MODOUT$ EQU     FLGTAB$+'M'-'A'
0077          00065 NFLAG$  EQU     FLGTAB$+'N'-'A'
0078          00066 OPREG$  EQU     FLGTAB$+'O'-'A'
007B          00067 RFLAG$  EQU     FLGTAB$+'R'-'A'
007C          00068 SFLAG$  EQU     FLGTAB$+'S'-'A'
007F          00069 VFLAG$  EQU     FLGTAB$+'V'-'A'
0089          00070 @KITSK  EQU     FLGTAB$+31
              00071 ;
0200          00072         ORG     200H+START$
              00073 ;
              00074 ;       Page 2 - Device Control Blocks
              00075 ;
0200 00       00076 BUR$    DB      00H             ;Bank use RAM
0201 FE       00077 BAR$    DB      0FEH            ;Bank available RAM
0202 14       00078 LBANK$  DB      20              ;Dir cyl & logical bank
0203 01       00079 JCLCB$  DB      1,0,0           ;Mini-DCB for JCL gets
     00 00 
0206 F40F     00080 DVRHI$  DW      DVREND$         ;Start of low I/O zone
0208 05       00081 KIDCB$  DB      5               ;Permit CTL, GET
0209 F008     00082         DW      KIDVR
020B 00       00083         DB      0,0,0,'KI'
     00 00 4B 49 
0210 07       00084 DODCB$  DB      7               ;Permit CTL, PUT, GET
0211 880B     00085         DW      DODVR
0213 00       00086         DB      0,0,0,'DO'
     00 00 44 4F 
0218 06       00087 PRDCB$  DB      6               ;Permit CTL, PUT
0219 010E     00088         DW      PRDVR
021B 00       00089         DB      0,0,0,'PR'
     00 00 50 52 
0220 15       00090 SIDCB$  DB      15H             ;Routed to *KI
0221 0802     00091         DW      KIDCB$
0223 0D       00092         DB      0DH,0,0,'SI'
     00 00 53 49 
0228 17       00093 SODCB$  DB      17H             ;Routed to *DO
0229 1002     00094         DW      DODCB$
022B 0F       00095         DB      0FH,0,0,'SO'
     00 00 53 4F 
0230 0A       00096 JLDCB$  DB      0AH,0,0,0AH,0,0,'JL'
     00 00 0A 00 00 4A 4C 
0238          00097 S1DCB$  EQU     $               ;1st spare DCB
0031          00098 DCBKL$  EQU     JLDCB$&0FFH+1   ;Non-killable DCB's
              00099 ;
              00100 ;       Now load the BOOT loader - part in this page
              00101 ;
0238          00102 *GET    BOOT4:3
              00103 ;BOOT4/ASM - LS-DOS 6.3
              00104 ;       SUBTTL  ''
              00106 *MOD
              00107 ;
0040          00108 KEYIN   EQU     40H
0066          00109 NMIVECT EQU     66H
021B          00110 DSPLY   EQU     21BH
1200          00111 BUFFER  EQU     1200H
43F6          00112 BOOTBUF EQU     43FFH-9
              00113 ;
              00114 ;       Boot loader routine read in by ROM, along with
              00115 ;        the lowcore I/O drivers.
              00116 ;       This section loads in SYSRES
              00117 ;
0238 FD217004 00118 LBOOT   LD      IY,DCT$         ;Set IY for FDCDVR use
023C FD7E09   00119         LD      A,(IY+9)        ;Directory track is
023F FD7705   00120         LD      (IY+5),A        ;  the current track
0242 3E04     00121         LD      A,4
0244 327B00   00122         LD      (FLGTAB$+'R'-'A'),A     ;Set retries
0247 3EC9     00123         LD      A,0C9H
0249 320E00   00124         LD      (FDDINT$),A     ;Return for disk driver
024C 3E12     00125         LD      A,18            ;5" sectors/track, dden
024E FDCB046E 00126         BIT     5,(IY+4)        ;Dbl sided?
0252 2801     00127         JR      Z,NOTDBL
0254 87       00128         ADD     A,A             ;Adjust to 36 sect/cyl
0255 32A502   00129 NOTDBL  LD      (SECTRK),A
              00130 ;
              00131 ;       Set up for a fragmented file
              00132 ;
0258 D9       00133         EXX
0259 0E06     00134         LD      C,6             ;Sectors/gran
025B CDB102   00135         CALL    GETEXT          ;Pick up extent 1
025E D9       00136         EXX
              00137 ;
025F CD6802   00138         CALL    LOAD            ;Read in sysres
0262 3EFB     00139         LD      A,0FBH          ;EI instruction
0264 32950F   00140         LD      (DISKEI),A      ;  stuffed into FDCDVR
0267 E9       00141         JP      (HL)            ;Continue system init
              00142 ;
0268 CD9702   00143 LOAD    CALL    RDBYTE          ;Get type code
026B 3D       00144         DEC     A
026C 200C     00145         JR      NZ,LOAD2        ;Bypass if not type 1
026E CD8802   00146         CALL    GETADR          ;Get blk len & load adr
0271 CD9702   00147 LOAD1   CALL    RDBYTE          ;Start reading the block
0274 77       00148         LD      (HL),A          ;Stuff into memory
0275 23       00149         INC     HL              ;Bump memory pointer
0276 10F9     00150         DJNZ    LOAD1           ;Loop for entire block
0278 18EE     00151         JR      LOAD            ;Restart the process
              00152 ;
027A 3D       00153 LOAD2   DEC     A               ;Test if type 2 (traadr)
027B 280B     00154         JR      Z,GETADR        ;Ah, go if transfer addr
027D CD9702   00155         CALL    RDBYTE          ;Assume comment,
0280 47       00156         LD      B,A             ;  get comment length
0281 CD9702   00157 LOAD3   CALL    RDBYTE          ;  & ignore it
0284 10FB     00158         DJNZ    LOAD3
0286 18E0     00159         JR      LOAD            ;Continue to read
              00160 ;
              00161 ;       got the transfer address type code
              00162 ;
0288 CD9702   00163 GETADR  CALL    RDBYTE          ;Get block length
028B 47       00164         LD      B,A
028C CD9702   00165         CALL    RDBYTE          ;Get lo-order load addr
028F 6F       00166         LD      L,A
0290 05       00167         DEC     B               ;Adj length for this byte
0291 CD9702   00168         CALL    RDBYTE          ;Get hi-order load addr
0294 67       00169         LD      H,A
0295 05       00170         DEC     B               ;Adj length for this byte
0296 C9       00171         RET
              00172 ;
              00173 ;       routine to read a byte
              00174 ;
0297 D9       00175 RDBYTE  EXX                     ;Switch memory/buf ptrs
0298 2C       00176         INC     L               ;Bump buf pointer
0299 2013     00177         JR      NZ,RDB2         ;Bypass disk i/o if more
029B C5       00178         PUSH    BC
029C 0609     00179         LD      B,9             ;Read sector function #
029E CD7004   00180         CALL    DCT$            ;Get another sector
02A1 C1       00181         POP     BC
02A2 1C       00182         INC     E               ;Bump sector counter
02A3 7B       00183         LD      A,E
02A4 D600     00184         SUB     $-$             ;Is this the last sector
02A5          00185 SECTRK  EQU     $-1
02A6 2002     00186         JR      NZ,RDB1         ;  on the cylinder?
02A8 5F       00187         LD      E,A             ;Yes, restart at 0
02A9 14       00188         INC     D               ;  & bump the cylinder up
02AA 05       00189 RDB1    DEC     B               ;Dec sectors this extent
02AB CCB102   00190         CALL    Z,GETEXT        ;Get next extent if 0
02AE 7E       00191 RDB2    LD      A,(HL)          ;P/u a byte
02AF D9       00192         EXX                     ;Exc mem/buf pointers
02B0 C9       00193         RET
              00194 ;
              00195 ;       Load DE track,sector, B sectors this extent
              00196 ;
              00197 GETEXT
02B1 DD23     00198         INC     IX              ;Index directory entry
02B3 DD23     00199         INC     IX              ;Pt at grans this ext.
02B5 DD7E00   00200         LD      A,(IX)
02B8 F5       00201         PUSH    AF              ;Save for later
02B9 07       00202         RLCA
02BA 07       00203         RLCA                    ;Normalize start gran
02BB 07       00204         RLCA
02BC E607     00205         AND     7
02BE CDCE02   00206         CALL    MULTCA          ;Start gran * grans/sec
02C1 5F       00207         LD      E,A             ;This is start sector
02C2 F1       00208         POP     AF
02C3 E61F     00209         AND     00011111B       ;Get total grans
02C5 3C       00210         INC     A               ;  this extent
02C6 CDCE02   00211         CALL    MULTCA          ;  * sect/gran
02C9 47       00212         LD      B,A             ;Sectors this extent
02CA DD56FF   00213         LD      D,(IX-1)        ;Cyl this extent
02CD C9       00214         RET
              00215 ;
              00216 ;       Short multiply C * A
              00217 ;
02CE C5       00218 MULTCA  PUSH    BC              ;Save sect/gran in C
02CF 57       00219         LD      D,A
02D0 AF       00220         XOR     A
02D1 0608     00221         LD      B,8
02D3 87       00222 MLTCA   ADD     A,A
02D4 CB21     00223         SLA     C
02D6 3001     00224         JR      NC,MLTCA1
02D8 82       00225         ADD     A,D
02D9 10F8     00226 MLTCA1  DJNZ    MLTCA
02DB C1       00227         POP     BC
02DC C9       00228         RET
              00229 ;
              00230 ;       Initialize the CRTC
              00231 ;
              00232 INITCRTC
02DD 01880F   00233         LD      BC,15<8!88H     ;Count, CRTC address reg
02E0 21FD02   00234         LD      HL,CRTCTAB
02E3 7E       00235 $A1     LD      A,(HL)
02E4 ED41     00236         OUT     (C),B           ;Pass reg # to CRTC
02E6 D389     00237         OUT     (89H),A         ;Pass value to CRTC reg
02E8 2B       00238         DEC     HL              ;Backup to next value
02E9 05       00239         DEC     B               ;To next lower reg
02EA F2E302   00240         JP      P,$A1
02ED C9       00241         RET
02EE 63       00242         DB      99              ;Horiz total MD
02EF 50       00243         DB      80              ;Horiz displayed MD
02F0 55       00244         DB      85              ;Horiz sync position MD
02F1 0A       00245         DB      10              ;Horiz sync width
02F2 19       00246         DB      25              ;Vertical total
02F3 04       00247         DB      4               ;Vertical total adjust
02F4 18       00248         DB      24              ;Vertical displayed
02F5 18       00249         DB      24              ;Vertical sync position
02F6 00       00250         DB      0               ;Interlace mode
02F7 09       00251         DB      9               ;Maximum scan line addr
02F8 65       00252         DB      65H             ;Cursor start
02F9 09       00253         DB      9               ;Cursor end
02FA 00       00254         DB      0               ;Start address (H)
02FB 00       00255         DB      0               ;Start address (L)
02FC 00       00256         DB      0               ;Cursor (H)
02FD 00       00257 CRTCTAB DB      0               ;Cursor (L)
02FE 00       00258         DC      -$&0FFH,0
     00 
              00259 ;
              00260 ;       System BOOT entry point, loaded by ROM
              00261 ;
0300          00262 CORE$   DEFL    $
4300          00263         ORG     4300H
4300 00       00264 BOOT    NOP
4301 FE14     00265         CP      14H             ;Directory track location
4302          00266 DIRTRK  EQU     $-1
4303 F3       00267         DI
4304 3E86     00268         LD      A,86H           ;Bring up the RAM
4306 D384     00269         OUT     (@OPREG),A
4308 327800   00270         LD      (OPREG$),A
430B 2100F8   00271         LD      HL,CRTBGN$      ;Clear video RAM
430E 1101F8   00272         LD      DE,CRTBGN$+1
4311 017F07   00273         LD      BC,CRTSIZE-1
4314 3620     00274         LD      (HL),' '
4316 EDB0     00275         LDIR
4318 21CD43   00276         LD      HL,NMIRET       ;Set NMI vector
431B 226700   00277         LD      (NMIVECT+1),HL
431E 3EC3     00278         LD      A,0C3H
4320 326600   00279         LD      (NMIVECT),A
4323 3EC9     00280         LD      A,0C9H          ;Stuff return for ints
4325 323800   00281         LD      (38H),A
              00282 ;
              00283 ;       Read the first 16 sectors of track 0
              00284 ;
4328 210002   00285         LD      HL,START$+200H  ;Pt to page 2
432B 55       00286         LD      D,L             ;Init to track 0, sec 0
432C 5D       00287         LD      E,L
432D CD7743   00288 RDBOOT  CALL    RDSEQ           ;Read a sector
4330 24       00289         INC     H               ;Bump to next page
4331 1C       00290         INC     E               ;Bump to next
4332 3E10     00291         LD      A,16
4334 BB       00292         CP      E               ;Loop if more
4335 20F6     00293         JR      NZ,RDBOOT
4337 CDDD02   00294         CALL    INITCRTC        ;Initialize the CRTC
              00295 ;
              00296 ;       Now set up to load SYSRES
              00297 ;
433A 3A0243   00298         LD      A,(DIRTRK)      ;P/u dir cyl
433D 327904   00299         LD      (DCT$+9),A      ;Update DCT to show DIR
4340 57       00300         LD      D,A             ;Set starting track and
4341 1E00     00301         LD      E,0             ;  init to read the GAT
4343 CD7443   00302         CALL    RDSECT          ;  into BUFFER
4346 3ACD12   00303         LD      A,(BUFFER+0CDH) ;Update DCT$ to show
4349 E620     00304         AND     20H             ;  the # of sides
434B 217404   00305         LD      HL,DCT$+4
434E B6       00306         OR      (HL)
434F 77       00307         LD      (HL),A
4350 1E04     00308         LD      E,4             ;Pt to SYS0 dir sector
4352 CD7443   00309         CALL    RDSECT          ;Read the SYS0 dir sec
4355 3A0012   00310         LD      A,(BUFFER)      ;Test if system disk
4358 E610     00311         AND     10H
435A 282D     00312         JR      Z,NOTSYS        ;Go if not
435C 211D12   00313         LD      HL,BUFFER+21+8  ;SYS0 extent info
435F 11F643   00314         LD      DE,BOOTBUF      ;Use 43FF-8
4362 010800   00315         LD      BC,8
4365 EDB8     00316         LDDR                    ;Store 1st four extents
4367 D5       00317         PUSH    DE              ;Pt IX to 1 byte
4368 DDE1     00318         POP     IX              ;  before extent info
436A D9       00319         EXX
436B 21FF12   00320         LD      HL,BUFFER+255   ;Init to buffer end
436E D9       00321         EXX
436F C33802   00322         JP      LBOOT           ;Load SYSRES
4372 00       00323         DB      0,0             ;Padding for posn
     00 
              00324 ;
              00325 ;       routine to read a sector
              00326 ;
4374 210012   00327 RDSECT  LD      HL,BUFFER       ;Set buffer
4377 0605     00328 RDSEQ   LD      B,5             ;Init retry counter
4379 C5       00329 RDS1    PUSH    BC              ;Save counter
437A E5       00330         PUSH    HL              ;Save for retries
437B CD9643   00331         CALL    READ            ;Attempt read
437E E1       00332         POP     HL
437F C1       00333         POP     BC
4380 E61C     00334         AND     1CH             ;Mask status
4382 C8       00335         RET     Z               ;Return if no error
4383 10F4     00336         DJNZ    RDS1            ;Loop for retry
4385 21E043   00337 GOTERR  LD      HL,DISKERR      ;"Disk error"
4388 DD       00338         DB      0DDH            ;Hide next instruction
4389 21EA43   00339 NOTSYS  LD      HL,NOSYS        ;"No system"
438C 010A00   00340         LD      BC,ERRLEN
438F 1193FB   00341         LD      DE,80*11+CRTBGN$+35     ;Middle of screen
4392 EDB0     00342         LDIR
4394 18FE     00343 HALTS   JR      HALTS           ;Wait for RESET
              00344 ;
4396 01F481   00345 READ    LD      BC,81F4H        ;Set DDEN, DS1, d.s. port
4399 ED41     00346         OUT     (C),B           ;Select it
439B 0D       00347         DEC     C               ;Point C to data reg
439C 3E18     00348         LD      A,18H           ;Seek command (6 ms)
439D          00349 BOOTST$ EQU     $-1             ;Set for boot step rate
              00350         IFNE    BOOTST$,439DH
              00351         ERR     'Boot step out of position'
              00352         ENDIF
439E ED51     00353         OUT     (C),D           ;Set desired track
43A0 CDD943   00354         CALL    FDCMD           ;Pass command & delay
43A3 DBF0     00355 SEEK1   IN      A,(0F0H)        ;Get status
43A5 CB47     00356         BIT     0,A             ;Busy?
43A7 20FA     00357         JR      NZ,SEEK1
43A9 7B       00358         LD      A,E             ;Set sector register
43AA D3F2     00359         OUT     (0F2H),A
43AC 3E81     00360         LD      A,81H           ;Set DDEN & DS1
43AE D3F4     00361         OUT     (0F4H),A
43B0 D5       00362         PUSH    DE
43B1 1102C1   00363         LD      DE,81H!40H<8!2  ;D=DS1 + DDEN + WSGEN
              00364                                 ;E=Mask to see DRQ
43B4 3E80     00365         LD      A,80H           ;FDC READ command
43B6 CDD943   00366         CALL    FDCMD           ;Pass to ctrlr & set B=0
43B9 3EC0     00367         LD      A,0C0H          ;Enable INTRQ & timeout
43BB D3E4     00368         OUT     (0E4H),A
43BD DBF0     00369 READLP1 IN      A,(0F0H)        ;Grab status
43BF A3       00370         AND     E               ;Test bit 1
43C0 28FB     00371         JR      Z,READLP1
43C2 EDA2     00372         INI
43C4 7A       00373         LD      A,D             ;Set DDEN & DS1 & WSGEN
43C5 D3F4     00374 READLP2 OUT     (0F4H),A        ;Continue to select
43C7 EDA2     00375         INI                     ;  while inputting
43C9 20FA     00376         JR      NZ,READLP2
43CB 18FE     00377         JR      $               ;Wait for NMI
43CD D1       00378 NMIRET  POP     DE              ;Pop interrupt ret
43CE D1       00379         POP     DE              ;Restore DE
43CF AF       00380         XOR     A               ;Disable INTRQ & timeout
43D0 D3E4     00381         OUT     (0E4H),A
43D2 3E81     00382         LD      A,81H           ;Reselect drive
43D4 D3F4     00383         OUT     (0F4H),A
43D6 DBF0     00384         IN      A,(0F0H)        ;Get status
43D8 C9       00385         RET
43D9 D3F0     00386 FDCMD   OUT     (0F0H),A        ;Give cmd to ctrlr
43DB 0618     00387         LD      B,24            ;Time delay
43DD 10FE     00388         DJNZ    $
43DF C9       00389         RET
43E0 44       00390 DISKERR DB      'Disk error'
     69 73 6B 20 65 72 72 6F
     72 
43EA 4E       00391 NOSYS   DB      'No system '
     6F 20 73 79 73 74 65 6D
     20 
000A          00392 ERRLEN  EQU     $-NOSYS         ;Length of error msg
43F4 00       00393         DC      -$&0FFH,0
     00 00 00 00 00 00 00 00
     00 00 00 
0400          00394         ORG     CORE$+256
              00396 ;
              00399 ;
              00400 ;       Page 3 - System stack and Sysinfo section
              00401 ;
0380          00402 STACK$  EQU     $-128           ;Start stack 128 bytes low
0382          00403 PAUSE@  EQU     STACK$+2        ;Where pause will be
              00404 ;
              00405 ;       Page 4 - Miscellaneous stuff
              00406 ;
0400 63       00407         DB      63H             ;Operating system version
0401 C9       00408 ZERO$   DB      0C9H            ;Config on BOOT, yes = 0
0401          00409 MAXDAY$ EQU     $-1             ;Max days per month
0402 1F       00410         DB      31,28,31,30,31,30,31,31,30,31,30,31
     1C 1F 1E 1F 1E 1F 1F 1E
     1F 1E 1F 
040E 00       00411 HIGH$   DS      2               ;Highest available memory
     00 
0410 4C       00412 PAKNAM$ DB      'LS-DOS63Level-';<631>
     53 2D 44 4F 53 36 33 4C
     65 76 65 6C 2D 
041E 31       00413         DB      '1'             ;<631>
              00414         IF      @BLD631H
041F 48       00415         DB      'H'             ;<631H>Level-1H
              00416         ELSE
              00417         IF      @BLD631G
              00418         DB      'G'             ;<631G>Level-1G
              00419         ELSE
              00420         IF      @BLD631F
              00421         DB      'F'             ;<631F>Level-1F
              00422         ELSE
              00423         IF      @BLD631E
              00424         DB      'E'             ;<631E>Level-1E
              00425         ELSE
              00426         IF      @BLD631D
              00427         DB      'D'             ;<631D>Level-1D
              00428         ELSE
              00429         IF      @BLD631C
              00430         DB      'C'             ;<631C>Level-1C
              00431         ELSE
              00432         DB      'B'             ;<631>Level-1B (tree base)
              00433         ENDIF                   ;C
              00434         ENDIF                   ;D
              00435         ENDIF                   ;E
              00436         ENDIF                   ;F
              00437         ENDIF                   ;G
              00438         ENDIF                   ;H
              00439 ;
              00440 ;       Command line input buffer & AUTO buffer area
              00441 ;
0420 0D       00442 INBUF$  DB      0DH             ;Input buffer - 80 bytes
0421 00       00443         DC      79,0
     00 00 00 00 00 00 00 00
     00 00 00 00 00 00 00 00
     00 00 00 00 00 00 00 00
     00 00 00 00 00 00 00 00
     00 00 00 00 00 00 00 00
     00 00 00 00 00 00 00 00
     00 00 00 00 00 00 00 00
     00 00 00 00 00 00 00 00
     00 00 00 00 00 00 00 00
     00 00 00 00 00 00 
              00444 ;
              00445 ;       System drive code tables
              00446 ;
0470          00447 DCT$    EQU     $               ;System drive code tables
0470 C33D0E   00448         JP      FDCDVR          ;Floppy drive 0
0473 44       00449         DB      44H,0C1H,0,27H,17,3-1<5+6-1,20
     C1 00 27 11 45 14 
047A C33D0E   00450         JP      FDCDVR          ;Floppy drive 1
047D 44       00451         DB      44H,42H,-1,27H,17,3-1<5+6-1,20
     42 FF 27 11 45 14 
0484 C9       00452         RET                     ;Disable drive #2
0485 3D0E     00453         DW      FDCDVR
0487 44       00454         DB      44H,44H,-1,27H,17,3-1<5+6-1,20
     44 FF 27 11 45 14 
048E C9       00455         RET                     ;Disable drive #3
048F 3D0E     00456         DW      FDCDVR
0491 44       00457         DB      44H,48H,-1,27H,17,3-1<5+6-1,20
     48 FF 27 11 45 14 
0498 C9       00458         RET                     ;Logical drive 4
0499 2A0F     00459         DW      FDCRET          
049B 00       00460         DB      0,0,0,27H,0,0,0
     00 00 27 00 00 00 
04A2 C9       00461         RET                     ;Logical drive 5
04A3 2A0F     00462         DW      FDCRET
04A5 00       00463         DB      0,0,0,27H,0,0,0
     00 00 27 00 00 00 
04AC C9       00464         RET                     ;Logical drive 6
04AD 2A0F     00465         DW      FDCRET
04AF 00       00466         DB      0,0,0,27H,0,0,0
     00 00 27 00 00 00 
04B6 C9       00467         RET                     ;Logical drive 7
04B7 2A0F     00468         DW      FDCRET
04B9 00       00469         DB      0,0,0,27H,0,0,0
     00 00 27 00 00 00 
              00470 ;
              00471 ;       SYSINFO - miscellaneous information
              00472 ;
04C0 FF       00473 DSKTYP$ DB      -1              ;0 = DATA, <> 0 = SYS
04C1 00       00474         DB      0               ;Reserved
04C2 00       00475 DTPMT$  DB      0               ;Date prompt at boot
04C3 00       00476 TMPMT$  DB      0               ;Time prompt at boot
04C4 00       00477 RSTOR$  DB      0               ;Suppress restores on BOOT
04C5 00       00478         DS      2               ;Reserved
     00 
04C7 53       00479 DAYTBL$ DB      'SunMonTueWedThuFriSat'
     75 6E 4D 6F 6E 54 75 65
     57 65 64 54 68 75 46 72
     69 53 61 74 
04DC 4A       00480 MONTBL$ DB      'JanFebMarAprMayJunJulAugSepOctNovDec'
     61 6E 46 65 62 4D 61 72
     41 70 72 4D 61 79 4A 75
     6E 4A 75 6C 41 75 67 53
     65 70 4F 63 74 4E 6F 76
     44 65 63 
              00481 ;
              00482 ;       End of low core assignments
              00483 ;
0500          00484 *GET    IODVR:3                 ;I/O driver, KEYIN, etc.
              00485 ;IODVR/ASM - LS-DOS 6.2
              00488 ;
001C          00489 HOME    EQU     1CH
001F          00490 CLRFRM  EQU     1FH
              00491 ;
              00492 ;       Log out routine - display & log
              00493 ;
0500 CD2D05   00494 @LOGOT  CALL    @DSPLY
              00495 ;
              00496 ;       Job log loger routine
              00497 ;
0503 3A3002   00498 @LOGER  LD      A,(JLDCB$)      ;If NIL, don't do
0506 EE08     00499         XOR     8               ;  anything
0508 E608     00500         AND     8
050A C8       00501         RET     Z
050B E5       00502         PUSH    HL              ;Save pointer to command
050C 211D05   00503         LD      HL,LOGBUF       ;Get time string into buf
050F E5       00504         PUSH    HL
0510 CD8D07   00505         CALL    @TIME
0513 E1       00506         POP     HL
0514 113002   00507         LD      DE,JLDCB$       ;Log the time
0517 CD3005   00508         CALL    @MSG
051A E1       00509         POP     HL              ;Log the command
051B 1813     00510         JR      @MSG
051D 68       00511 LOGBUF  DB      'hh:mm:ss  ',3
     68 3A 6D 6D 3A 73 73 20
     20 03 
              00512 ;
              00513 ;       Line print routine
              00514 ;
0528 111802   00515 @PRINT  LD      DE,PRDCB$       ;Printer DCB
052B 1803     00516         JR      @MSG
              00517 ;
              00518 ;       Line display routine
              00519 ;
052D 111002   00520 @DSPLY  LD      DE,DODCB$       ;Video DCB
              00521 ;
              00522 ;       Device message routine
              00523 ;
              00524 *MOD
0530 E5       00525 @MSG    PUSH    HL              ;Save pointer to message
0531 7E       00526 $B1     LD      A,(HL)          ;P/u a message character
0532 FE03     00527         CP      3               ;Exit on ETX
0534 280D     00528         JR      Z,$B3
0536 FE0D     00529         CP      CR              ;Exit & put on ENTER
0538 2806     00530         JR      Z,$B2
053A C44506   00531         CALL    NZ,@PUT         ;Else put the char
053D 23       00532         INC     HL              ;  & loop on no error
053E 28F1     00533         JR      Z,$B1           ;  else fall thru & exit
0540 CC4506   00534 $B2     CALL    Z,@PUT
0543 E1       00535 $B3     POP     HL
0544 C9       00536         RET
              00537 ;
              00538 ;       Clear screen routine
              00539 ;
0545 3E1C     00540 @CLS    LD      A,HOME          ;Cursor home to 0,0
0547 CD4D05   00541         CALL    DSPBYT
054A C0       00542         RET     NZ              ;Return on error
054B 3E1F     00543         LD      A,CLRFRM        ;Clear to end of frame
054D D5       00544 DSPBYT  PUSH    DE
054E CD4206   00545         CALL    @DSP
0551 D1       00546         POP     DE
0552 C9       00547         RET
              00548 ;
              00549 ;       Check and Clear  bit SVC
              00550 ;
              00551 @CKBRKC
0553 E5       00552         PUSH    HL              ;Save registers
0554 217400   00553         LD      HL,KFLAG$       ;Point to KFLAG$
0557 CB46     00554         BIT     0,(HL)          ;Check break bit
0559 281A     00555         JR      Z,NOBRK         ;  and ret if none
055B F5       00556         PUSH    AF              ;Save flags
055C C5       00557         PUSH    BC
055D D5       00558         PUSH    DE
055E CB86     00559 BRKTEST RES     0,(HL)          ;Reset the break bit
0560 01000B   00560         LD      BC,0B00H        ;Wait more than 1/30
0563 CD8203   00561         CALL    PAUSE@          ;  of a second
0566 CB46     00562         BIT     0,(HL)          ;Test the bit again
0568 20F4     00563         JR      NZ,BRKTEST      ;Loop until gone
056A 110802   00564         LD      DE,KIDCB$       ;Point at keyboard &
056D 3E03     00565         LD      A,03            ;  clear buffer with
056F CD2306   00566         CALL    @CTL            ;  control 3 call
0572 D1       00567         POP     DE
0573 C1       00568         POP     BC              ;Recover registers
0574 F1       00569         POP     AF              ;Recover FLAGS
0575 E1       00570 NOBRK   POP     HL
0576 C9       00571         RET
              00572 ;
              00573 ;       Keyboard line input routine
              00574 ;
              00575 *MOD
              00576 ;
              00577 ;       Backspace to beginning of line
              00578 ;
0577 CDDB05   00579 $C4     CALL    $C6             ;Backspace
057A 2B       00580         DEC     HL              ;Get the char prior
057B 7E       00581         LD      A,(HL)          ;  to the current
057C 23       00582         INC     HL
057D FE0A     00583         CP      0AH             ;Return if line feed
057F C8       00584         RET     Z
0580 78       00585 $C5     LD      A,B             ;Check for empty buffer
0581 B9       00586         CP      C
0582 20F3     00587         JR      NZ,$C4          ;Loop if not
0584 C9       00588         RET                     ;  else return
0585 E5       00589 @KEYIN  PUSH    HL              ;Save buffer pointer
0586 48       00590         LD      C,B             ;Set C = buffer size
0587 112806   00591 $C1     LD      DE,@KEY         ;Init for standard input
058A 3A7C00   00592         LD      A,(SFLAG$)      ;If JCL is active,
058D E620     00593         AND     20H             ;  then use the JCL input
058F 2802     00594         JR      Z,$C0           ;Must loop here in case
0591 1E30     00595         LD      E,@JCL&0FFH     ;  JCL exits with //STOP
0593 ED539805 00596 $C0     LD      ($C1A+1),DE
0597 CD0000   00597 $C1A    CALL    $-$             ;Get a key
059A 203D     00598         JR      NZ,$C3B         ;Back on error
059C FE80     00599         CP      80H             ;Break?
059E 2875     00600         JR      Z,$C10
05A0 FE20     00601         CP      20H             ;Go if not a control
05A2 3020     00602         JR      NC,$C2
05A4 FE0D     00603         CP      0DH             ;Carriage return?
05A6 286E     00604         JR      Z,$C11
05A8 FE1F     00605         CP      1FH             ;Clear?
05AA 2825     00606         JR      Z,$C3
05AC 118705   00607         LD      DE,$C1          ;Set return address
05AF D5       00608         PUSH    DE
05B0 FE08     00609         CP      08H             ;Backspace?
05B2 2827     00610         JR      Z,$C6
05B4 FE18     00611         CP      18H             ;Backspace to BOL?
05B6 28C8     00612         JR      Z,$C5
05B8 FE09     00613         CP      09H             ;Tab?
05BA 283C     00614         JR      Z,$C8
05BC FE12     00615         CP      'R'&1FH         ;CTL-R?
05BE 282A     00616         JR      Z,$C7
05C0 FE0A     00617         CP      0AH             ;Line feed?
05C2 C0       00618         RET     NZ              ;Ret if none above
05C3 D1       00619         POP     DE              ;Pop the return
05C4 77       00620 $C2     LD      (HL),A          ;Stuff the char
05C5 78       00621         LD      A,B             ;Check on buffer full
05C6 B7       00622         OR      A
05C7 28BE     00623         JR      Z,$C1           ;Loop if so
05C9 7E       00624         LD      A,(HL)          ;  else get char
05CA 23       00625         INC     HL              ;  & bump pointer
05CB 05       00626         DEC     B               ;Count down
05CC CD4206   00627         CALL    @DSP            ;Display entry
05CF 1806     00628         JR      $C3A            ;  then loop
              00629 ;
              00630 ;       Clear the screen invoked
              00631 ;
05D1 CD4505   00632 $C3     CALL    @CLS
05D4 41       00633         LD      B,C             ;Reset to start of
05D5 E1       00634         POP     HL              ;  line & start of
05D6 E5       00635         PUSH    HL              ;  buffer
05D7 28AE     00636 $C3A    JR      Z,$C1
05D9 183B     00637 $C3B    JR      $C11
              00638 ;
              00639 ;       Backspace key entry
              00640 ;
05DB 78       00641 $C6     LD      A,B             ;If buffer is empty,
05DC B9       00642         CP      C               ;  return
05DD C8       00643         RET     Z
05DE 2B       00644         DEC     HL              ;  else do the backspace
05DF 7E       00645         LD      A,(HL)
05E0 FE0A     00646         CP      0AH             ;Last char a linefeed?
05E2 23       00647         INC     HL
05E3 C8       00648         RET     Z               ;Return if so
05E4 2B       00649         DEC     HL
05E5 04       00650         INC     B               ;Add back one char
05E6 3E08     00651         LD      A,8             ;Backspace the cursor
05E8 1858     00652         JR      @DSP
              00653 ;
              00654 ;       Test if repeat last command
              00655 ;
05EA 3A6C00   00656 $C7     LD      A,(CFLAG$)      ;Test if SYS1 KEYIN bit
05ED E604     00657         AND     4               ;  is set (bit 2)
05EF C8       00658         RET     Z               ;Ignore CTL if not
05F0 78       00659         LD      A,B             ;If not at 1st position,
05F1 B9       00660         CP      C               ;  don't permit it
05F2 C0       00661         RET     NZ
05F3 E1       00662         POP     HL              ;Pop return to KEY
05F4 E1       00663         POP     HL              ;Point to command buffer
05F5 C32D05   00664         JP      @DSPLY          ;Display the old command
              00665 ;
              00666 ;       Tab entered
              00667 ;
05F8 E5       00668 $C8     PUSH    HL              ;Get pos on line
05F9 CDF10D   00669         CALL    ADDR_2_ROWCOL   ;Get row,col in HL
05FC 7D       00670         LD      A,L             ;Xfer column to A
05FD E1       00671         POP     HL
05FE E607     00672         AND     7
0600 ED44     00673         NEG                     ;Negate and add tab
0602 C608     00674         ADD     A,8
0604 5F       00675         LD      E,A             ;Reg E has tab length
0605 78       00676 $C9     LD      A,B             ;Check on buffer full
0606 B7       00677         OR      A
0607 C8       00678         RET     Z
0608 3E20     00679         LD      A,' '           ;Put spaces until
060A 77       00680         LD      (HL),A          ;  tab expanded
060B 23       00681         INC     HL
060C CD4D05   00682         CALL    DSPBYT
060F C0       00683         RET     NZ
0610 05       00684         DEC     B               ;Dec buffer remaining
0611 1D       00685         DEC     E               ;Dec tab count
0612 C8       00686         RET     Z
0613 18F0     00687         JR      $C9
              00688 ;
              00689 ;       Exit KEYIN routine
              00690 ;
0615 37       00691 $C10    SCF                     ;BREAK exit with CF
0616 F5       00692 $C11    PUSH    AF              ;Save flag
0617 3E0D     00693         LD      A,0DH           ;Stuff CR at end
0619 77       00694         LD      (HL),A
061A CD4206   00695         CALL    @DSP            ;  & display it
061D 79       00696         LD      A,C             ;Calculate # of chars
061E 90       00697         SUB     B               ;  entered
061F 47       00698         LD      B,A
0620 F1       00699         POP     AF              ;Rcvr flag
0621 E1       00700         POP     HL              ;Restore buffer ptr
0622 C9       00701         RET
              00702 ;
              00703 ;       Byte I/O device handler
              00704 ;               C => character if PUT or CTL
              00705 ;               DE => Device control block
              00706 ;
              00707 *MOD
0623 C5       00708 @CTL    PUSH    BC
0624 0604     00709         LD      B,4             ;Bit 2, CTL
0626 1820     00710         JR      IOBGN
0628 CD3506   00711 @KEY    CALL    @KBD            ;Scan the keyboard
062B C8       00712         RET     Z               ;Ret if key available
062C B7       00713         OR      A               ;Return if error
062D 28F9     00714         JR      Z,@KEY
062F C9       00715         RET
0630 110302   00716 @JCL    LD      DE,JCLCB$       ;JCL file FCB
0633 1803     00717         JR      @GET
0635 110802   00718 @KBD    LD      DE,KIDCB$       ;Keyboard DCB
0638 C5       00719 @GET    PUSH    BC
0639 0601     00720         LD      B,1             ;Bit 0, GET
063B 180B     00721         JR      IOBGN
063D 111802   00722 @PRT    LD      DE,PRDCB$       ;Printer DCB
0640 1803     00723         JR      @PUT
0642 111002   00724 @DSP    LD      DE,DODCB$       ;Video DCB
0645 C5       00725 @PUT    PUSH    BC
0646 0602     00726         LD      B,2             ;Bit 1, PUT
0648 DDE5     00727 IOBGN   PUSH    IX              ;Save the registers
064A E5       00728         PUSH    HL
064B D5       00729         PUSH    DE              ;Xfer DCB to IX
064C DDE1     00730         POP     IX
064E D5       00731         PUSH    DE
064F 4F       00732         LD      C,A             ;Xfer the I/O char
0650 218006   00733         LD      HL,@RSTREG      ;Restore register routine
0653 3A0202   00734         LD      A,(LBANK$)      ;If bank 0 is not
0656 B7       00735         OR      A               ;  resident, need to
0657 280E     00736         JR      Z,$D0           ;  get it resident!
              00737 ;
              00738 ;       Some other bank is resident - invoke bank 0
              00739 ;
0659 C5       00740         PUSH    BC              ;Save reg again
065A AF       00741         XOR     A               ;Prepare for bank-0
065B 47       00742         LD      B,A
065C 4F       00743         LD      C,A
065D CD7708   00744         CALL    @BANK           ;Invoke bank-0
0660 60       00745         LD      H,B             ;Get old bank data
0661 69       00746         LD      L,C             ;  into reg HL
0662 C1       00747         POP     BC              ;Rcvr BC
0663 E5       00748         PUSH    HL              ;Bank data to stack
0664 217906   00749         LD      HL,RSTBNK       ;Set return address
0667 E5       00750 $D0     PUSH    HL              ;  to restore registers
0668 1A       00751         LD      A,(DE)          ;P/u DCB type byte
0669 B7       00752         OR      A
066A C8       00753         RET     Z               ;Back if nothing
066B FE08     00754         CP      8               ;Ck on GET/PUT/CTL
066D 301A     00755         JR      NC,@CHNIO       ;Branch if special
066F DD6E01   00756         LD      L,(IX+1)        ;  else p/u the vector
0672 DD6602   00757         LD      H,(IX+2)
0675 78       00758 $D1     LD      A,B             ;Xfer I/O code
0676 FE02     00759         CP      2               ;Set flags state
0678 E9       00760         JP      (HL)
0679 C1       00761 RSTBNK  POP     BC              ;Get old bank data
067A F5       00762         PUSH    AF              ;Can't affect AF
067B 79       00763         LD      A,C             ;Request to A
067C CD7708   00764         CALL    @BANK           ;Bring back original bank
067F F1       00765         POP     AF
0680 D1       00766 @RSTREG POP     DE              ;Restore regs
0681 E1       00767         POP     HL
0682 DDE1     00768         POP     IX
0684 C1       00769         POP     BC
0685 C9       00770         RET
              00771 ;
0686 E5       00772 $D2     PUSH    HL
0687 DDE1     00773         POP     IX
0689 DD6E01   00774 @CHNIO  LD      L,(IX+1)        ;P/u vector address
068C DD6602   00775         LD      H,(IX+2)
068F DD7E00   00776 $D3     LD      A,(IX+0)        ;P/u the DCB type
0692 B7       00777         OR      A               ;File Control Block?
0693 FA0013   00778         JP      M,@BYTEIO
0696 CB5F     00779         BIT     3,A             ;Test NIL bit 2nd
0698 2024     00780         JR      NZ,$D5
069A CB67     00781         BIT     4,A             ;Routed?
069C 20E8     00782         JR      NZ,$D2          ;Go get routed DCB
069E CB6F     00783         BIT     5,A             ;If not linked, then
06A0 28D3     00784         JR      Z,$D1           ;  must be filtered
06A2 E5       00785         PUSH    HL              ;Point to the link DCB
06A3 DDE1     00786         POP     IX
06A5 DD7003   00787         LD      (IX+3),B        ;Save the direction
06A8 DDE5     00788         PUSH    IX
06AA CD8906   00789         CALL    @CHNIO          ;I/O to 1st device
06AD DDE1     00790         POP     IX
06AF DD4603   00791         LD      B,(IX+3)        ;P/u the direction
06B2 200C     00792         JR      NZ,$D6          ;Go on NZ flag
              00793 ;
              00794 ;       Z-flag on return - check input/output
              00795 ;
06B4 CB40     00796         BIT     0,B             ;If input & got char,
06B6 DD6E04   00797 $D4     LD      L,(IX+4)        ;  p/u the linked DCB
06B9 DD6605   00798         LD      H,(IX+5)
06BC 28C8     00799         JR      Z,$D2
06BE BF       00800 $D5     CP      A
06BF C9       00801         RET
              00802 ;
              00803 ;       1st link got NZ condition - if input, get link
              00804 ;
06C0 CB40     00805 $D6     BIT     0,B             ;Was it input/output?
06C2 2803     00806         JR      Z,$D7           ;Output is error
06C4 B7       00807         OR      A               ;If A=0, then no input
06C5 28EF     00808         JR      Z,$D4
06C7 B7       00809 $D7     OR      A
06C8 C9       00810         RET
06C9          00811 *GET    MULDIV:3                ;16-bit MULT & DIV
              00812 ;MULDIV/ASM - 16 x 8 multiplication & division
              00815 *MOD
              00816 ;
              00817 ;       Multiply HL by A - SVC 91
              00818 ;       HL => multiplicand
              00819 ;       A  => multiplier
              00820 ;       HLA <= 24-bit result
              00821 ;       DE destroyed
              00822 ;
06C9 C5       00823 @MUL16  PUSH    BC              ;Save reg BC
06CA EB       00824         EX      DE,HL           ;Multiplicand to DE
06CB 4F       00825         LD      C,A             ;  & multiplier to C
06CC 210000   00826         LD      HL,0            ;Init value to zero
06CF 7D       00827         LD      A,L             ;  in regs HLA
06D0 0608     00828         LD      B,8             ;Init for 8-bit mult
06D2 29       00829 $E1     ADD     HL,HL           ;Shift to next place
06D3 17       00830         RLA                     ;Use A for bits 16-23
06D4 CB01     00831         RLC     C               ;Multiply this bit?
06D6 3003     00832         JR      NC,$E2          ;Go if not
06D8 19       00833         ADD     HL,DE           ;Else add multiplicand
06D9 CE00     00834         ADC     A,0             ;  & any overflow to 16
06DB 10F5     00835 $E2     DJNZ    $E1             ;Loop for 8 bits
06DD 4F       00836         LD      C,A             ;Tempy save
06DE 7D       00837         LD      A,L             ;Xfer low-order to A
06DF 6C       00838         LD      L,H             ;Xfer mid-order to L
06E0 61       00839         LD      H,C             ;Xfer hi-order to H
06E1 C1       00840         POP     BC
06E2 C9       00841         RET
              00842 ;
              00843 ;       Divide HL by A - SVC 94
              00844 ;       HL => dividend
              00845 ;       A  => divisor
              00846 ;       HL <= resulting quotient
              00847 ;       A  <= remainder
              00848 ;
              00849 *MOD
06E3 D5       00850 @DIV16  PUSH    DE              ;Save this reg pair
06E4 57       00851         LD      D,A             ;Xfer divisor to D
06E5 1E10     00852         LD      E,16            ;Init for 16-bits
06E7 AF       00853         XOR     A
06E8 29       00854 $F1     ADD     HL,HL           ;Rotate dividend
06E9 17       00855         RLA                     ;  & subtract divisor if
06EA 3803     00856         JR      C,$F2           ;  carry into bit-16
06EC BA       00857         CP      D               ;Compare divisor
06ED 3802     00858         JR      C,$F3           ;Go if no subtract
06EF 92       00859 $F2     SUB     D               ;  else subtract divisor
06F0 2C       00860         INC     L               ;Set lo-order
06F1 1D       00861 $F3     DEC     E               ;Count down one bit
06F2 20F4     00862         JR      NZ,$F1          ;Loop for 16-bits
06F4 D1       00863         POP     DE
06F5 C9       00864         RET
              00865 ;
              00866 ;       @HEXDEC - SVC 97
              00867 ;       Routine to convert 16-bit hexadecimal to decimal
              00868 ;       HL => value
              00869 ;       DE => buffer pointer of 5-character buffer
              00870 ;       HL <= destroyed (always set to zero)
              00871 ;       DE <= Buffer+5
              00872 ;       BC <= destroyed
              00873 ;       Z  <= set
              00874 ;
              00875 *MOD
06F6 0605     00876 @HEXDEC LD      B,5             ;Length max
06F8 3E20     00877 @HEXD   LD      A,' '           ;Load blank
06FA 12       00878 HEXDEC1 LD      (DE),A          ;To string
06FB 13       00879         INC     DE              ;Bump pointer
06FC 10FC     00880         DJNZ    HEXDEC1         ;Go for length
06FE D5       00881         PUSH    DE              ;Save end +1
06FF 1B       00882         DEC     DE              ;Adjust back
0700 3E0A     00883 HEXDEC2 LD      A,10            ;Base to convert to
0702 CDE306   00884         CALL    @DIV16          ;HL+A  =  HL/A
0705 C630     00885         ADD     A,'0'           ;Add ASCII to result
0707 12       00886         LD      (DE),A          ;  to user string
0708 1B       00887         DEC     DE              ;Move back
              00888 ;
              00889 ;       Check if done
              00890 ;
0709 7C       00891         LD      A,H             ;Get subtotal remainder
070A B5       00892         OR      L               ;Done?
070B 20F3     00893         JR      NZ,HEXDEC2      ;Go till completed
070D D1       00894         POP     DE              ;Restore end+1
070E C9       00895         RET                     ;Return Z
              00896 ;
070F          00897 *GET    CLOCKS:3                ;Hardware task stuff
              00898 ;CLOCKS/ASM - LS-DOS 6.2
              00901 *MOD
              00902 ;
              00903 ;       Model IV time clock & blinking cursor
              00904 ;
070F 3C       00905 TIMETBL DB      60,60,24,30     ;Sec/min, min/hr, hr/day
     3C 18 1E 
              00906 TIMTSK$
0713 3A970B   00907         LD      A,(CRSAVE)      ;If cursor not on,
0716 B7       00908         OR      A               ;  then don't blink
0717 217F00   00909         LD      HL,VFLAG$       ;Point to video flag
071A 2829     00910         JR      Z,$H2
              00911                                 ;Check if blinking
071C CB7E     00912         BIT     7,(HL)          ;Check system INHIBIT
071E CBBE     00913         RES     7,(HL)          ;Allow blink next time
0720 2023     00914         JR      NZ,$H2
0722 34       00915         INC     (HL)            ;Increment the counter
0723 CB5E     00916         BIT     3,(HL)          ;  & see if to 8
0725 281E     00917         JR      Z,$H2           ;Not this time
0727 CB9E     00918         RES     3,(HL)          ;Reset counter
0729 CB76     00919         BIT     6,(HL)          ;Check if SOLID cursor
072B 2802     00920         JR      Z,NOSOLID       ;If not, then blink
072D CBEE     00921         SET     5,(HL)          ;Force SOLID mode
072F CD1708   00922 NOSOLID CALL    ENADIS_DO_RAM   ;Bring up the video RAM
0732 7E       00923         LD      A,(HL)          ;Grab the toggle bit
0733 EE20     00924         XOR     20H             ;  and flip it
0735 77       00925         LD      (HL),A
0736 E620     00926         AND     20H             ;Was it on?
0738 ED5B950B 00927         LD      DE,(CURSOR)     ;Get the cursor pos
073C 3A970B   00928         LD      A,(CRSAVE)      ;  and char under cursor
073F 2003     00929         JR      NZ,$H1          ;Put character if flip on
0741 3A980B   00930         LD      A,(CRSCHAR)     ;  else put the cursor
0744 12       00931 $H1     LD      (DE),A          ;Put the char
0745 DD210F07 00932 $H2     LD      IX,TIMETBL      ;Point to data area
0749 DD3503   00933         DEC     (IX+3)          ;Count down by 30
074C C0       00934         RET     NZ              ;Back if not one second
              00935         IF      @HZ50
              00936         LD      (IX+3),25       ;Set for 50 hertz
              00937 HERTZ$  EQU     $-1
              00938         ELSE                    ;  else use 60 hertz
074D DD36031E 00939         LD      (IX+3),30       ;Reset for one second
0750          00940 HERTZ$  EQU     $-1
              00941         ENDIF
0751 CB66     00942         BIT     4,(HL)          ;Is clock on? (VFLAG$)
0753 2804     00943         JR      Z,$H3           ;Go if off
0755 118707   00944         LD      DE,CLOCK        ;Set to display clock
0758 D5       00945         PUSH    DE
0759 0603     00946 $H3     LD      B,3
075B 212D00   00947         LD      HL,TIME$
075E 110F07   00948         LD      DE,TIMETBL      ;Pt to max sec, min, hr
0761 34       00949 TIMER1  INC     (HL)            ;Bump time parm
0762 1A       00950         LD      A,(DE)
0763 96       00951         SUB     (HL)
0764 C0       00952         RET     NZ              ;Ret if not max
0765 77       00953         LD      (HL),A          ;  else set to 0
0766 2C       00954         INC     L               ;Pt to next parm
0767 1C       00955         INC     E
0768 10F7     00956         DJNZ    TIMER1          ;Loop thru 3 parms
              00957 ;
              00958 ;       Update date at midnight
              00959 ;
076A 2E35     00960         LD      L,DATE$+2&0FFH  ;Point to day of month
076C 7E       00961         LD      A,(HL)          ;Get the month
076D B7       00962         OR      A               ;See if date used
076E C8       00963         RET     Z               ;Back if not
076F 2D       00964         DEC     L
0770 110104   00965         LD      DE,MAXDAY$      ;Point to test table
0773 34       00966         INC     (HL)            ;Bump the day
0774 83       00967         ADD     A,E
0775 5F       00968         LD      E,A
0776 1A       00969         LD      A,(DE)          ;P/u max days
0777 BE       00970         CP      (HL)            ;Is day in range?
0778 D0       00971         RET     NC              ;Return if it is
0779 3601     00972         LD      (HL),1          ;  else reset day to 1
077B 2C       00973         INC     L               ;  & bump the month
077C 34       00974         INC     (HL)
077D 7E       00975         LD      A,(HL)          ;If went past Dec,
077E D60D     00976         SUB     12+1            ;  then need to fix
0780 D8       00977         RET     C
0781 3601     00978         LD      (HL),1          ;Correct to Jan
0783 2D       00979         DEC     L               ;Backup to year
0784 2D       00980         DEC     L
0785 34       00981         INC     (HL)
0786 C9       00982         RET
              00983 ;
              00984 ;       Clock display processor
              00985 ;
              00986 CLOCK
0787 CD1708   00987         CALL    ENADIS_DO_RAM   ;Bring up the video
078A 2145F8   00988         LD      HL,CRTBGN$+69   ;Point to display CRT
078D 112F00   00989 @TIME   LD      DE,TIME$+2      ;Point to time$
0790 0E3A     00990         LD      C,':'           ;Set the separator
0792 0603     00991 TIME1   LD      B,3             ;Init for three fields
0794 1A       00992 TIME2   LD      A,(DE)          ;Get a field item
0795 362F     00993         LD      (HL),2FH        ;Init display
0797 34       00994 TIME3   INC     (HL)            ;Bump until proper digit
0798 D60A     00995         SUB     10
079A 30FB     00996         JR      NC,TIME3
079C C63A     00997         ADD     A,3AH           ;Correct the remainder
079E 23       00998         INC     HL              ;Bump to next display
079F 77       00999         LD      (HL),A          ;  & stuff the digit
07A0 23       01000         INC     HL
07A1 05       01001         DEC     B
07A2 C8       01002         RET     Z               ;Back when done
07A3 71       01003         LD      (HL),C          ;  else stuff separator
07A4 23       01004         INC     HL
07A5 1B       01005         DEC     DE              ;Point to next field
07A6 18EC     01006         JR      TIME2           ;  & loop
              01007 ;
              01008 ;       Return formatted date, HL => user buffer
              01009 ;
              01010         IF      @BLD631
              01011 DATELO$                         ;<631>
              01012         ELSE
              01013 @DATE
              01014         ENDIF
07A8 113500   01015         LD      DE,DATE$+2
07AB 0E2F     01016         LD      C,'/'
07AD 18E3     01017         JR      TIME1
              01018 ;
07AF 0000     01019 PCSAVE$ DW      00              ;PC at entry to RST 38
              01020 ;
              01021 ;       Dynamic Trace routine
              01022 ;
              01023 TRACE_INT
07B1 B307     01024         DW      $+2
07B3 2AAF07   01025         LD      HL,(PCSAVE$)
07B6 EB       01026         EX      DE,HL           ;Program counter to DE
07B7 CD1708   01027         CALL    ENADIS_DO_RAM   ;Bring up the video
07BA 213EF8   01028         LD      HL,CRTBGN$+62   ;Crt trace adr
              01029 ;
              01030 ;       Hexadecimal display routine
              01031 ;
07BD 7A       01032 @HEX16  LD      A,D             ;Convert reg D to
07BE CDC207   01033         CALL    @HEX8           ;  two hex digits
07C1 7B       01034         LD      A,E             ;Convert reg E to
07C2 F5       01035 @HEX8   PUSH    AF              ;  two hex digits
07C3 1F       01036         RRA                     ;Do left nybble first
07C4 1F       01037         RRA
07C5 1F       01038         RRA
07C6 1F       01039         RRA
07C7 CDCB07   01040         CALL    HXD1            ;Bits 0-3 stuffed in hex
07CA F1       01041         POP     AF              ;Reget the byte
07CB E60F     01042 HXD1    AND     0FH             ;  & use right nybble
07CD C690     01043         ADD     A,90H           ;Convert nybble to hex
07CF 27       01044         DAA
07D0 CE40     01045         ADC     A,40H
07D2 27       01046         DAA
07D3 77       01047         LD      (HL),A          ;Stuff in (HL)
07D4 23       01048         INC     HL
07D5 C9       01049         RET
              01050 ;
              01051 ;       Scan for PAUSE or BREAK & set KFLAG$
              01052 ;
F480          01053 SHIFT   EQU     0F480H
              01054         IF      @USA
F401          01055 KB1     EQU     0F401H
              01056         ENDIF
              01057         IF      @GERMAN
              01058 KB1     EQU     0F420H
              01059         ENDIF
              01060         IF      @FRENCH
              01061 KB1     EQU     0F408H
              01062         ENDIF
F440          01063 KB7     EQU     0F440H
07D6 CD1708   01064 KCK@    CALL    ENADIS_DO_RAM   ;Bring up the keyboard
07D9 217400   01065         LD      HL,KFLAG$       ;Hang onto flag
07DC 3A80F4   01066         LD      A,(SHIFT)       ;P/u SHIFT row & ignore
07DF E607     01067         AND     7               ;  CTRL key pressed
07E1 2F       01068         CPL
07E2 CB57     01069         BIT     2,A
07E4 C8       01070         RET     Z               ;Back if CTRL
              01071 ;
              01072 ;       Set carry flag if a SHIFT key is down
              01073 ;
07E5 C601     01074         ADD     A,1             ;Set CF if no SHIFT
07E7 3F       01075         CCF                     ;Set CF if SHIFT
07E8 300B     01076         JR      NC,KCK1         ;No pause if no SHIFT
07EA 3A01F4   01077         LD      A,(KB1)         ;Test for "@"
              01078         IF      @USA
07ED CB47     01079         BIT     0,A
              01080         ENDIF
              01081         IF      @INTL
              01082         BIT     4,A             ;Foriegn keyboard
              01083         ENDIF
07EF 280B     01084         JR      Z,KCK1A         ;Bypass if no "@"
07F1 CBCE     01085         SET     1,(HL)          ;Turn on pause bit
07F3 1807     01086         JR      KCK1A
              01087 ;
              01088 ;       Inhibit test of unshifted BREAK if nested ENA_DO
              01089 ;
07F5 3A3508   01090 KCK1    LD      A,(OPREG_SV_PTR) ;If not at highest level
07F8 D66F     01091         SUB     OPREG_SV_AREA+1&0FFH ;  then don't allow
07FA 2009     01092         JR      NZ,KCK1B        ;  tasker BREAK handler
07FC 3A40F4   01093 KCK1A   LD      A,(KB7)         ;Check on BREAK & ENTER
07FF CB47     01094         BIT     0,A             ;Check on ENTER
0801 2802     01095         JR      Z,KCK1B         ;Go if not
0803 CBD6     01096         SET     2,(HL)          ;  else note set
0805 CB57     01097 KCK1B   BIT     2,A             ;Is  depressed?
0807 F5       01098         PUSH    AF
0808 280B     01099         JR      Z,KCK2          ;Go if not
080A 3809     01100         JR      C,KCK2          ;Ignore if shifted
080C 3A7C00   01101         LD      A,(SFLAG$)      ;Permit break bit only
080F CB67     01102         BIT     4,A             ;  if BREAK enabled?
0811 2002     01103         JR      NZ,KCK2
0813 CBC6     01104         SET     0,(HL)          ;Turn on BREAK bit
0815 F1       01105 KCK2    POP     AF              ;C=shift, NZ=break
0816 C9       01106         RET
              01107 ;
              01108 ;       Routine to enable video RAM & change stack if necessary
              01109 ;
              01110 *MOD
              01111 ENADIS_DO_RAM
0817 F3       01112         DI                      ;Can't while we test stack
0818 226B08   01113         LD      (HLSAV),HL      ;Save HL but not on stack
081B F5       01114         PUSH    AF              ;Save AF
081C E1       01115         POP     HL
081D 226608   01116         LD      (AFSAV),HL
0820 21030C   01117         LD      HL,0C03H        ;Can't exceed X'F3FC'
0823 39       01118         ADD     HL,SP
0824 3009     01119         JR      NC,$I1
              01120 ;
              01121 ;       Switch to the system stack
              01122 ;
0826 E1       01123         POP     HL              ;Transfer RET address
0827 ED736308 01124         LD      (SPSAV),SP      ;Save stack pointer
082B 314003   01125         LD      SP,STACK$-40H   ;Keep room at top
082E E5       01126         PUSH    HL              ;Put RET back
082F 214608   01127 $I1     LD      HL,DIS_DO_RAM   ;Stack return to disable
0832 E3       01128         EX      (SP),HL         ;  video RAM below RET
0833 E5       01129         PUSH    HL
0834 216E08   01130         LD      HL,OPREG_SV_AREA
0835          01131 OPREG_SV_PTR    EQU     $-2
0837 23       01132         INC     HL              ;Get next save location
0838 3A7800   01133         LD      A,(OPREG$)      ;P/u port mask
083B 3002     01134         JR      NC,$I2          ;Bypass if NC (no stack switch)
083D E67F     01135         AND     7FH             ;Strip bit 7 to use as flag
083F 77       01136 $I2     LD      (HL),A          ;Save current state
0840 E6FC     01137         AND     0FCH            ;Strip SEL1 & SEL0
0842 F682     01138         OR      82H             ;Set SEL1,0 = (1,0) & NZ condx
0844 1812     01139         JR      DOOPREG         ;Set new assignment
              01140 ;
              01141 ;       Routine to disable video RAM
              01142 ;
              01143 DIS_DO_RAM
0846 F3       01144         DI                      ;Interrupts off
0847 226B08   01145         LD      (HLSAV),HL      ;Save off of stack
084A F5       01146         PUSH    AF
084B E1       01147         POP     HL              ;Save AF
084C 226608   01148         LD      (AFSAV),HL
084F 2A3508   01149         LD      HL,(OPREG_SV_PTR)
0852 7E       01150         LD      A,(HL)          ;P/u previous state
0853 CB7F     01151         BIT     7,A             ;Test if we switch stack
0855 CBFF     01152         SET     7,A             ;Make sure PAGE is set
0857 2B       01153         DEC     HL
              01154 ;
0858 223508   01155 DOOPREG LD      (OPREG_SV_PTR),HL
085B 327800   01156         LD      (OPREG$),A      ;Restore port image
085E D384     01157         OUT     (@OPREG),A      ;  and the port
0860 2003     01158         JR      NZ,$I3
              01159 ;
              01160 ;       Switch back to the old stack
              01161 ;
0862 310000   01162         LD      SP,$-$          ;Get the old stack
0863          01163 SPSAV   EQU     $-2
0865 210000   01164 $I3     LD      HL,$-$
0866          01165 AFSAV   EQU     $-2
0868 E5       01166         PUSH    HL              ;Restore AF
0869 F1       01167         POP     AF
086A 210000   01168         LD      HL,$-$          ;Restore HL
086B          01169 HLSAV   EQU     $-2
086D FB       01170         EI                      ;Interrupts back on
086E C9       01171         RET
086E          01172 OPREG_SV_AREA   EQU     $-1
086F 00       01173         DB      0,0,0,0,0,0,0,0
     00 00 00 00 00 00 00 
              01174 ;
              01175 ;       Bank selection SVC handler
              01176 ;       HL=> transfer address for function B=0
              01177 ;       C => Bank request <0-2>; Set bit 7 to transfer
              01178 ;       B => Request function
              01179 ;               0 => Select bank C
              01180 ;               1 => Reset in-use bit of bank C
              01181 ;               2 => Test in-use bit of bank C
              01182 ;               3 => Set in-use bit of bank C
              01183 ;
              01184 *MOD
              01185 @BANK
0877 E67F     01186         AND     7FH             ;Strip possible bit 7
0879 FE03     01187         CP      2+1             ;Bank out of range?
087B D2ED0D   01188         JP      NC,PERR
087E 05       01189         DEC     B               ;Check option
087F FAB308   01190         JP      M,$J3           ;Go if bank select
0882 0E86     01191         LD      C,86H           ;Set for reset BUR$
0884 2819     01192         JR      Z,$J1           ;Go if function 1
0886 0E46     01193         LD      C,46H           ;Set for test BUR$
0888 05       01194         DEC     B
0889 2814     01195         JR      Z,$J1           ;Go if function 2
088B 05       01196         DEC     B
088C 2809     01197         JR      Z,$J0           ;Go on set BUR$
088E 05       01198         DEC     B
088F C2ED0D   01199 PERRX   JP      NZ,PERR         ;SVC parameter error
0892 3A0202   01200         LD      A,(LBANK$)      ;P/u current bank
0895 BF       01201         CP      A
0896 C9       01202         RET
0897 47       01203 $J0     LD      B,A             ;Save the bank requested
0898 CD9F08   01204         CALL    $J1             ;Test if in use already
089B C0       01205         RET     NZ              ;Back if error
089C 78       01206         LD      A,B             ;Reget the request #
089D 0EC6     01207         LD      C,0C6H          ;Set for set BUR$
089F E607     01208 $J1     AND     7               ;Strip to bank 0-7
08A1 07       01209         RLCA                    ;Shift <0-2> to <3-5>
08A2 07       01210         RLCA
08A3 07       01211         RLCA
08A4 B1       01212         OR      C               ;Merge the code type
08A5 32B008   01213         LD      ($J2+1),A       ;Change the OP code
08A8 AF       01214         XOR     A               ;Init Z-flag
08A9 3E08     01215         LD      A,8             ;Init "Device not avail
08AB E5       01216         PUSH    HL              ;Don't alter HL
08AC 210002   01217         LD      HL,BUR$         ;Point to bank-used-RAM
08AF CB46     01218 $J2     BIT     0,(HL)          ;*** Modified instruction
08B1 E1       01219         POP     HL
08B2 C9       01220         RET
08B3 E5       01221 $J3     PUSH    HL              ;Ck if stack is in upper
08B4 210580   01222         LD      HL,8005H        ;  bank area
08B7 39       01223         ADD     HL,SP
08B8 E1       01224         POP     HL
08B9 DAED0D   01225         JP      C,PERR          ;Error if > X'7FFE'
08BC FE01     01226         CP      1               ;Change <0, 1, 2, 3>
08BE 17       01227         RLA                     ;  to <1, 2, 4, 6>
08BF 47       01228         LD      B,A             ;  & save for later
08C0 3A0102   01229         LD      A,(BAR$)        ;P/u Bank Avail Ram
08C3 A0       01230         AND     B               ;Is the bank installed?
08C4 20C9     01231         JR      NZ,PERRX        ;Error if not in machine
08C6 78       01232         LD      A,B             ;Get the requested bank
08C7 1F       01233         RRA                     ;Change <1, 2, 4> to
08C8 3F       01234         CCF                     ;  <0, 2, 3> {CF on 0
08C9 CE00     01235         ADC     A,0             ;  switched to 2 & 4}
08CB 07       01236         RLCA                    ;Shift bits 0-1
08CC 07       01237         RLCA                    ;  to 4-5 (MBIT0,1)
08CD 07       01238         RLCA
08CE 07       01239         RLCA
08CF 47       01240         LD      B,A             ;Save bit mask
08D0 3A7800   01241         LD      A,(OPREG$)      ;P/u current memory
08D3 E68F     01242         AND     08FH            ;  configuration &
08D5 B0       01243         OR      B               ;  mask off old &
08D6 327800   01244         LD      (OPREG$),A      ;  merge the new
08D9 D384     01245         OUT     (@OPREG),A      ;Switch the hardware
08DB 3A0202   01246         LD      A,(LBANK$)      ;Get old bank #
08DE 47       01247         LD      B,A             ;  & save it
08DF 79       01248         LD      A,C             ;P/u new bank #
08E0 E67F     01249         AND     7FH             ;Strip any bit-7
08E2 320202   01250         LD      (LBANK$),A      ;  & save new bank #
08E5 A9       01251         XOR     C               ;Keep bit-7
08E6 B0       01252         OR      B               ;Merge in new bank #
08E7 4F       01253         LD      C,A             ;  & replace into C
08E8 CB79     01254         BIT     7,C             ;Transfer to new bank?
08EA 0600     01255         LD      B,0             ;Init for invoke later
08EC C8       01256         RET     Z               ;No if bit-7 = 0
08ED E3       01257         EX      (SP),HL         ;Exchange RET with new
08EE BF       01258         CP      A               ;  transfer & go to it
08EF C9       01259         RET
08F0          01260 @$SYS   EQU     $               ;Pointer for @GTMOD
              01261         IF      @USA
08F0          01262 *GET    KIDVR:3                 ;Keyboard driver
              01263 ;KIDVR/ASM - LS-DOS 6.2
              01266 *MOD
              01267 ;
000A          01268 LF      EQU     10
000D          01269 CR      EQU     13
F401          01270 KB0     EQU     0F401H          ;Row 0 RAM address
F440          01271 KB6     EQU     0F440H          ;Row 6 RAM address
F480          01272 SHIFT   EQU     0F480H          ;Row 7 RAM address
              01273 ;
08F0 1831     01274 KIDVR   JR      KIBGN           ;Branch around linkage
08F2 870B     01275         DW      KILAST          ;Last byte used
08F4 03       01276         DB      3,'$KI'
     24 4B 49 
08F8 0802     01277         DW      KIDCB$          ;Pointer to DCB
08FA 0000     01278         DW      0               ;Spare
08FC 00       01279 KIDATA$ DB      0               ;Last key entered
08FD 00       01280         DB      0               ;Repeat time check
0002          01281 RPTINIT EQU     $-KIDATA$
08FE 16       01282         DB      22              ;22 * 33.3ms = .733 sec
0003          01283 RPTRATE EQU     $-KIDATA$
08FF 02       01284         DB      2               ;2 x RTC rate
0004          01285 KBROW0  EQU     $-KIDATA$
0900 FF       01286         DB      -1,-1,-1,-1     ;Image of rows 0-3
     FF FF FF 
0008          01287 KBROW4  EQU     $-KIDATA$
0904 FF       01288         DB      -1,-1           ;Image of rows 4-5
     FF 
000A          01289 KBROW6  EQU     $-KIDATA$
0906 FF       01290         DB      -1,-1           ;Image of rows 6-7
     FF 
              01291 ;
              01292 ;       Conversion table for keyboard row 7/8
              01293 ;
0908 0D       01294 KBTBL   DB      CR,1DH,1FH,1FH  ; 
     1D 1F 1F 
090C 80       01295         DB      80H,0,0BH,1BH   ; 
     00 0B 1B 
0910 0A       01296         DB      LF,1AH,8,18H    ; 
     1A 08 18 
0914 09       01297         DB      9,19H,20H,20H   ; 
     19 20 20 
0918 81       01298         DB      81H,91H,82H,92H ; 
     91 82 92 
091C 83       01299         DB      83H,93H         ;
     93 
              01300 ;
              01301 ;       Table to generate 5B-5F, 7B-7F
              01302 ;
091E 2C       01303 SPCLTB  DB      ',/.;',CR
     2F 2E 3B 0D 
              01304 ;
              01305 ;       Entry to keyboard driver
              01306 ;
0923 79       01307 KIBGN   LD      A,C             ;Get the character
0924 F5       01308         PUSH    AF              ;Save flags
0925 CD8900   01309         CALL    @KITSK          ;Hook for KI task
0928 F1       01310         POP     AF
              01311 ;
              01312 ;       Screen print (Control-*) processing
              01313 ;
0929 CDD50A   01314         CALL    TYPAHD          ;Chain downstream
092C D0       01315         RET     NC              ;Ret if not 
092D F5       01316         PUSH    AF              ;Save flag state
092E FE3A     01317         CP      ':'
0930 2802     01318         JR      Z,$K1           ;Go if screen print
0932 F1       01319         POP     AF
0933 C9       01320         RET
              01321 ;
              01322 ;       Perform a screen print
              01323 ;
0934 F1       01324 $K1     POP     AF              ;Clean the stack
0935 3A6D00   01325 @VDPRT  LD      A,(DFLAG$)      ;Check on Graphic bit
0938 07       01326         RLCA
0939 3E3E     01327         LD      A,3EH           ;Init for LD a,'.'
093B 3002     01328         JR      NC,$+4          ;Go if not Graphic
093D 3EFE     01329         LD      A,0FEH          ;Change to CPR n
093F 325C09   01330         LD      ($K4),A         ;Stuff cpr or ld
0942 217400   01331         LD      HL,KFLAG$       ;Reset the BREAK bit
0945 CB86     01332         RES     0,(HL)
0947 E5       01333         PUSH    HL              ;Save on stack
0948 210000   01334         LD      HL,0            ;Init for row,col
094B 0601     01335 $K2     LD      B,1             ;Get a character at the
094D CD990B   01336         CALL    @VDCTL          ;  row-H, col-L
0950 2027     01337         JR      NZ,$K6          ;Go on error
0952 FE20     01338         CP      20H
0954 3002     01339         JR      NC,$+4          ;Convert control codes
0956 C640     01340         ADD     A,40H           ;  to cap A-Z, +
0958 FE80     01341         CP      80H             ;Cvrt anything from X'80'
095A 3802     01342         JR      C,$K5           ;  thru X'FF' to a '.'
095C 3E2E     01343 $K4     LD      A,'.'           ;  unless graphic bit set
095E CD3D06   01344 $K5     CALL    @PRT            ;Print the char & loop
0961 2016     01345         JR      NZ,$K6
0963 2C       01346         INC     L               ;Bump column counter
0964 7D       01347         LD      A,L             ;Check for end-of-line
0965 D650     01348         SUB     80
0967 20E2     01349         JR      NZ,$K2          ;Loop if not EOL
0969 6F       01350         LD      L,A             ;Reset to column 0
096A 2D       01351         DEC     L               ;Adj for CR force
096B E3       01352         EX      (SP),HL         ;Get KFLAG$
096C CB46     01353         BIT     0,(HL)          ;Exit with A=0 on
096E E3       01354         EX      (SP),HL         ;  entrance of BREAK
096F 2008     01355         JR      NZ,$K6
0971 24       01356         INC     H               ;Bump row counter
0972 7C       01357         LD      A,H             ;Test for end of screen
0973 FE18     01358         CP      24
0975 3E0D     01359         LD      A,CR
0977 20E5     01360         JR      NZ,$K5          ;Put the CR & loop
0979 3E0D     01361 $K6     LD      A,CR            ;Close out with CR if
097B CD3D06   01362         CALL    @PRT            ;  BREAK key detected
097E E1       01363         POP     HL              ;Pop the KFLAG
097F CB86     01364         RES     0,(HL)          ;  & reset BREAK bit
0981 1832     01365         JR      NOCHAR
              01366 ;
              01367 ;       Driver to scan the keyboard
              01368 ;
              01369 *MOD
0983 DD21FC08 01370 KISCAN  LD      IX,KIDATA$      ;Point to data area
0987 210009   01371         LD      HL,KIDATA$+KBROW0 ;Load kbd image start
098A 0101F4   01372         LD      BC,KB0          ;Load start of keyboard
098D 1600     01373         LD      D,0             ;Zero the key counter
098F 0A       01374 $L1     LD      A,(BC)          ;Load 1st char from kbd
0990 5F       01375         LD      E,A
0991 AE       01376         XOR     (HL)            ;XOR with old value
0992 2026     01377         JR      NZ,$L2          ;Go if different
0994 14       01378         INC     D               ;Bump key counter
0995 23       01379         INC     HL              ;Bump image pointer
0996 CB01     01380         RLC     C               ;Go to next row
0998 F28F09   01381         JP      P,$L1           ;Loop until end of rows
099B 0A       01382         LD      A,(BC)          ;Get row 7
099C E678     01383         AND     078H            ;Strip SHIFT, CTL
099E 5F       01384         LD      E,A
099F AE       01385         XOR     (HL)
09A0 2018     01386         JR      NZ,$L2
09A2 DD7E00   01387         LD      A,(IX+0)        ;Key down? It's same as
09A5 B7       01388         OR      A               ;  the last if so
09A6 280D     01389         JR      Z,NOCHAR        ;Ret if no key
09A8 3A2C00   01390         LD      A,(TIMER$)      ;Do we repeat the
09AB DD9601   01391         SUB     (IX+1)          ;  same key?
09AE DD9602   01392         SUB     (IX+RPTINIT)    ;Beyond 0.75 seconds?
09B1 0A       01393         LD      A,(BC)          ;Get back row 7
09B2 5F       01394         LD      E,A
09B3 3869     01395         JR      C,$L10          ;Go if yes
09B5 F601     01396 NOCHAR  OR      1               ;Else don't repeat
09B7 3E00     01397         LD      A,0             ;Show NZ with A=0
09B9 C9       01398         RET
              01399 ;
              01400 ;       Found change in key matrix
              01401 ;
09BA 73       01402 $L2     LD      (HL),E          ;Stuff KB image with new
09BB A3       01403         AND     E               ;  KB row value
09BC CA880A   01404         JP      Z,NOKEY         ;Go if new is none
              01405 ;
              01406 ;       Convert the depressed key
              01407 ;
09BF 5F       01408         LD      E,A             ;Save the active bit
09C0 7A       01409         LD      A,D             ;Calculate 8 * row
09C1 07       01410         RLCA
09C2 07       01411         RLCA
09C3 07       01412         RLCA
09C4 57       01413         LD      D,A             ;Save 8 * row
09C5 0E01     01414         LD      C,1             ;Add 8 * row + column
09C7 79       01415 $L3     LD      A,C
09C8 A3       01416         AND     E               ;Check if bits match
09C9 2019     01417         JR      NZ,$L6          ;Go if match
09CB 14       01418         INC     D               ;  else bump value
09CC CB01     01419         RLC     C               ;Shift compare bit
09CE 18F7     01420         JR      $L3             ;Loop to test next
              01421 ;
              01422 ;       Key pressed was not an alpha
              01423 ;
09D0 D690     01424 $L4     SUB     90H             ;Adjust for non-alpha
09D2 3052     01425         JR      NC,$L9          ;Go if special key
09D4 C640     01426         ADD     A,40H           ;Cvrt to numeric/symbol
09D6 FE3C     01427         CP      3CH             ;Manipulate to get
09D8 3802     01428         JR      C,$L5           ;  proper code
09DA EE10     01429         XOR     10H
09DC CB43     01430 $L5     BIT     0,E             ;Check SHIFT
09DE 2860     01431         JR      Z,$L11          ;Go if unshift
09E0 EE10     01432         XOR     10H             ;  else adjust for SHIFT
09E2 185C     01433         JR      $L11
              01434 ;
              01435 ;       Found a key - Set up the function codes
              01436 ;
09E4 3A80F4   01437 $L6     LD      A,(SHIFT)       ;P/u the SHIFT key
09E7 5F       01438         LD      E,A             ;Merge RH & LH Shift keys
09E8 E602     01439         AND     2               ;Only merge bit 1
09EA 0F       01440         RRCA                    ;Bit 1 to bit 0
09EB B3       01441         OR      E               ;Merge bits 0 & 1
09EC 5F       01442         LD      E,A             ;Value of (RHorLH) shift
09ED 7A       01443         LD      A,D             ;Load semi-converted
09EE C660     01444         ADD     A,60H           ;If alpha, convert to
09F0 FE80     01445         CP      80H             ;  correct value
09F2 217400   01446         LD      HL,KFLAG$
09F5 30D9     01447         JR      NC,$L4          ;Go if not alpha
              01448 ;
              01449 ;       Alpha <@-Z> - If caps lock or ,
              01450 ;       Convert to caps unless CLEAR
              01451 ;
09F7 CB53     01452         BIT     2,E             ;CTRL key down?
09F9 2018     01453         JR      NZ,CTLA2Z       ;CTRL sets <00-1A>
09FB FE60     01454         CP      60H             ;Invert @ and `
09FD 2004     01455         JR      NZ,$L7
09FF EE20     01456         XOR     20H             ;Invert & bypass test
0A01 180A     01457         JR      $L8             ;  for CAPs lock
0A03 DDCB0A4E 01458 $L7     BIT     1,(IX+KBROW6)   ;If CLEAR, don't test
0A07 2004     01459         JR      NZ,$L8          ;  for CAPs lock
0A09 CB6E     01460         BIT     5,(HL)          ;Caps lock?
0A0B 2031     01461         JR      NZ,TGLCASE
0A0D CB43     01462 $L8     BIT     0,E             ;Shift key down?
0A0F 282F     01463         JR      Z,$L11          ;Bypass if not shifted
0A11 182B     01464         JR      TGLCASE         ;Convert to upper case
0A13 D660     01465 CTLA2Z  SUB     60H             ;Convert CTRL A-Z
0A15 2029     01466         JR      NZ,$L11         ;Go on A-Z
0A17 CB43     01467         BIT     0,E             ;Shifted?
0A19 37       01468         SCF                     ;Set C-flag for CTL-@
0A1A C8       01469         RET     Z               ;  & return if unshifted
0A1B 3E1C     01470         LD      A,1CH           ;  else set EOF error
0A1D C9       01471         RET
0A1E 3A2C00   01472 $L10    LD      A,(TIMER$)      ;Advance time check
0A21 DD8603   01473         ADD     A,(IX+RPTRATE)  ;  by 0.067 seconds
0A24 1872     01474         JR      $L12            ;Go output the key
              01475 ;
              01476 ;       Special keys - rows 6 & 7
              01477 ;
0A26 FE0B     01478 $L9     CP      11              ;Compress F1-F3 keys
0A28 284F     01479         JR      Z,CAPSKEY       ;  while checking for CAP
0A2A 3802     01480         JR      C,$+4           ;  F1-F3 to 8-10
0A2C D604     01481         SUB     4
0A2E 210809   01482         LD      HL,KBTBL        ;Pt to special char table
0A31 07       01483         RLCA                    ;Index into table,
0A32 CB43     01484         BIT     0,E             ;  shifted code is +1
0A34 2801     01485         JR      Z,$+3
0A36 3C       01486         INC     A
0A37 4F       01487         LD      C,A             ;Index the table
0A38 0600     01488         LD      B,0
0A3A 09       01489         ADD     HL,BC
0A3B 7E       01490         LD      A,(HL)          ;Load char from table
0A3C 1802     01491         JR      $L11            ;Bypass restore of char
0A3E EE20     01492 TGLCASE XOR     20H             ;Toggle the case
0A40 FE80     01493 $L11    CP      80H             ;BREAK key?
0A42 200F     01494         JR      NZ,$L11A        ;Ck on  disable
0A44 217C00   01495         LD      HL,SFLAG$       ;Break disabled?
0A47 CB66     01496         BIT     4,(HL)
0A49 2007     01497         JR      NZ,$L11B        ;Don't set bit if disabl
0A4B 217400   01498         LD      HL,KFLAG$
0A4E CBC6     01499         SET     0,(HL)          ;  otherwise set it
0A50 1801     01500         JR      $L11A
0A52 17       01501 $L11B   RLA                     ;Rotate bit-7 out
0A53 DDCB0A4E 01502 $L11A   BIT     1,(IX+KBROW6)   ;CLEAR key pressed?
0A57 280E     01503         JR      Z,NOTALPH       ;Go if not down
0A59 57       01504         LD      D,A             ;Save code
0A5A CBAF     01505         RES     5,A             ;Set to upper-case for
0A5C D641     01506         SUB     'A'             ;  test A-Z
0A5E FE1A     01507         CP      'Z'-'A'+1
0A60 7A       01508         LD      A,D             ;Get back actual char
0A61 3002     01509         JR      NC,$+4          ;Go if not A-Z
0A63 EE20     01510         XOR     20H             ;Shift keyboard case
0A65 F680     01511         OR      80H             ;Set bit 7 for CLEAR key
0A67 CB43     01512 NOTALPH BIT     0,E             ;SHIFT key down?
0A69 2819     01513         JR      Z,FIXCLR        ;Go if not
0A6B FE9F     01514 GOTSHFT CP      9FH             ;Shift-clear?
0A6D 2813     01515         JR      Z,FIXSCL        ;Go if so
0A6F FE20     01516 TSTSPA  CP      20H             ;Shift 0 or shift sp?
0A71 2016     01517         JR      NZ,KEYOK        ;Go if not
0A73 DDCB0846 01518         BIT     0,(IX+KBROW4)   ;Ck zero key
0A77 2810     01519         JR      Z,KEYOK         ;Go if not down
              01520 ;
              01521 ;       Toggle the caps lock bit in the KFLAG$
              01522 ;
0A79 3E20     01523 CAPSKEY LD      A,20H           ;CAPs wasn't 20H
0A7B 217400   01524 CASHK$  LD      HL,KFLAG$       ;Reverse case by
0A7E AE       01525         XOR     (HL)            ;  flipping bit 5
0A7F 77       01526         LD      (HL),A
0A80 1806     01527         JR      NOKEY
0A82 EE80     01528 FIXSCL  XOR     80H             ;Reset bit 7
0A84 FE9F     01529 FIXCLR  CP      9FH             ;Clear key?
0A86 2001     01530         JR      NZ,KEYOK        ;Go if not
0A88 AF       01531 NOKEY   XOR     A
0A89 DD7700   01532 KEYOK   LD      (IX+0),A
0A8C 018401   01533         LD      BC,0184H        ;Delay
0A8F CD8203   01534 TYPHK$  CALL    PAUSE@
0A92 3A2C00   01535         LD      A,(TIMER$)      ;Set initialization
0A95 DD8602   01536 DELAY2  ADD     A,(IX+RPTINIT)  ;  repeat key delay
0A98 DD7701   01537 $L12    LD      (IX+1),A        ;Save new repeat time
0A9B DD7E00   01538         LD      A,(IX+0)        ;Check if any key
0A9E B7       01539         OR      A               ;  code was saved
0A9F CAB509   01540         JP      Z,NOCHAR        ;Ret if none
0AA2 CB53     01541         BIT     2,E             ;Shift key down?
0AA4 37       01542         SCF                     ;Init carry
0AA5 2004     01543         JR      NZ,SPECL        ;Ret if CTRL
0AA7 3F       01544         CCF
0AA8 CB7F     01545 DVREXIT BIT     7,A             ;Z-flag set on non-CLEAR
0AAA C8       01546         RET     Z               ;Go if not CLEAR+key
0AAB F5       01547 SPECL   PUSH    AF              ;Save code
0AAC 211E09   01548 $L13    LD      HL,SPCLTB       ;Special char table
0AAF CBBF     01549         RES     7,A             ;Turn off "CLEAR"
0AB1 015B05   01550         LD      BC,5<8!5BH      ;5 chars, starting char
0AB4 3001     01551         JR      NC,$+3          ;  if not CTRL
0AB6 05       01552         DEC     B               ;  else only 4
0AB7 BE       01553 SPCLLP  CP      (HL)            ;Is this it?
0AB8 2812     01554         JR      Z,HIT           ;Go if so
0ABA EE10     01555         XOR     10H             ;Flip shift state
0ABC BE       01556         CP      (HL)            ;Is that it?
0ABD 280B     01557         JR      Z,HITWS         ;Go if so
0ABF EE10     01558         XOR     10H             ;Flip back
0AC1 23       01559         INC     HL              ;Bump specl table ptr
0AC2 0C       01560         INC     C               ;Bump "convert to" char
0AC3 10F2     01561         DJNZ    SPCLLP          ;Loop through table
0AC5 F1       01562         POP     AF              ;Not found in table
0AC6 380A     01563         JR      C,CKCTL2        ;Ck CTL for C-flag
0AC8 BF       01564 CKCTL1  CP      A               ;Set Z-flag
0AC9 C9       01565         RET
0ACA CBE9     01566 HITWS   SET     5,C             ;Move to LC set
0ACC F1       01567 HIT     POP     AF              ;Restore orig char
0ACD 79       01568         LD      A,C             ;Load converted one
0ACE 30F8     01569 CKCTL   JR      NC,CKCTL1       ;Go if ctl key not down
0AD0 E61F     01570         AND     1FH             ;Force ctl code
0AD2 BF       01571 CKCTL2  CP      A               ;Set Z-flag
0AD3 37       01572         SCF                     ;Set C-flag for CTRL
0AD4 C9       01573         RET
              01574 ;
              01575 ;       Check the type ahead buffer for any character
              01576 ;
              01577 *MOD
              01578 TYPAHD
0AD5 CD1708   01579         CALL    ENADIS_DO_RAM   ;Bring up Keyboard ram
0AD8 2180FF   01580         LD      HL,TYPBUF       ;P/u start of type buffer
0ADB 36FF     01581         LD      (HL),0FFH       ;Turn off type ahead
0ADD 381D     01582         JR      C,$M1           ;Go on @GET
0ADF 2842     01583         JR      Z,TYPON         ;No PUT to *KI
0AE1 FE03     01584         CP      3               ;CTL 3 function?
0AE3 CA650B   01585         JP      Z,CLRTYP        ;Clear buffer if so
0AE6 3C       01586         INC     A
0AE7 2803     01587         JR      Z,CTLFF         ;Go if CTL 255 function
0AE9 AF       01588         XOR     A               ;Nothing done, No error
0AEA 1837     01589         JR      TYPON
              01590 ;
              01591 ;       Handle CTL-255 - scan keyboard into user rowbuf
              01592 ;
              01593 CTLFF
0AEC 2101F4   01594         LD      HL,KB0          ;Start of keyboard image
0AEF 0608     01595         LD      B,8             ;Do 8 rows
0AF1 7E       01596 $M0     LD      A,(HL)          ;P/u the image
0AF2 FD7700   01597         LD      (IY),A          ;  and xfer to user buffer
0AF5 FD23     01598         INC     IY
0AF7 CB15     01599         RL      L
0AF9 10F6     01600         DJNZ    $M0
0AFB C9       01601         RET
              01602 ;
0AFC E5       01603 $M1     PUSH    HL
0AFD 23       01604         INC     HL              ;Bump to PUT pointer
0AFE 7E       01605         LD      A,(HL)          ;  & pick it up
0AFF 23       01606         INC     HL              ;Bump to GET pointer
0B00 BE       01607         CP      (HL)            ;The same?
0B01 281C     01608         JR      Z,$M4           ;Go if so
0B03 E5       01609         PUSH    HL              ;Save pointer to GETPTR
0B04 5E       01610         LD      E,(HL)          ;P/u offset to buffer
0B05 23       01611         INC     HL              ;Pt to buffer start
0B06 1600     01612         LD      D,0             ;Add offset to start
0B08 19       01613         ADD     HL,DE           ;  to point to char posn
0B09 46       01614         LD      B,(HL)          ;GET the stored char
0B0A E1       01615         POP     HL              ;Rcvr GETPTR
0B0B 34       01616         INC     (HL)            ;Bump by 1 for char
0B0C 3E50     01617         LD      A,80            ;Check for >80
0B0E BE       01618         CP      (HL)            ;  after INC
0B0F 3002     01619         JR      NC,$M2          ;Go if not at end
0B11 3600     01620         LD      (HL),0          ;Reset to start of buf
0B13 7E       01621 $M2     LD      A,(HL)          ;If we emptied the
0B14 2B       01622         DEC     HL              ;  type-ahead buffer,
0B15 BE       01623         CP      (HL)            ;  update KFLAG$
0B16 CC6A0B   01624         CALL    Z,R7KFLG        ;Reset bit-7 if empty
0B19 E1       01625         POP     HL              ;Pointed to & get switch
0B1A 3600     01626         LD      (HL),0          ;Turn type back on
0B1C 78       01627         LD      A,B             ;Transfer char/flag
0B1D BF       01628         CP      A               ;Set flag "Z"
0B1E C9       01629         RET
              01630 ;
              01631 ;       No character in type ahead buffer - get from kbd
              01632 ;
0B1F CD8309   01633 $M4     CALL    KISCAN          ;Call keyboard driver
0B22 E1       01634         POP     HL              ;Rcvr switch
0B23 3600     01635 TYPON   LD      (HL),0          ;Type ahead back on
0B25 C9       01636         RET
              01637 ;
              01638 ;       Type ahead task 10 - scans keyboard & saves key
              01639 ;
0B26 280B     01640 TYPTSK$ DW      $M5             ;Task entry for processor
0B28 3A6D00   01641 $M5     LD      A,(DFLAG$)      ;If type-ahead suppressed
0B2B E602     01642         AND     2H              ;  then return
0B2D C8       01643         RET     Z
0B2E CD1708   01644         CALL    ENADIS_DO_RAM   ;Bring up the keyboard
0B31 2180FF   01645         LD      HL,TYPBUF       ;P/u type switch
0B34 7E       01646         LD      A,(HL)          ;If previous driver is
0B35 B7       01647         OR      A               ;  currently executing,
0B36 C0       01648         RET     NZ              ;  do not stack more keys
0B37 23       01649         INC     HL              ;Bump to PUTPTR
0B38 E5       01650         PUSH    HL              ;  & save it
0B39 CD8309   01651 KIHOOK  CALL    KISCAN          ;  and scan for a character
0B3C E1       01652         POP     HL
0B3D C0       01653         RET     NZ              ;Ret if no char
0B3E F5       01654         PUSH    AF              ;  else xfer char
0B3F C1       01655         POP     BC              ;  & flag to BC
0B40 FE80     01656         CP      80H             ;Check for 
0B42 F5       01657         PUSH    AF
0B43 E5       01658         PUSH    HL
0B44 CC660B   01659         CALL    Z,$M6           ;If so clear type buf
0B47 E1       01660         POP     HL              ;Restore
0B48 F1       01661         POP     AF
0B49 FEC0     01662         CP      0C0H            ;If CLEAR @, reset keybuf
0B4B 2819     01663         JR      Z,$M6
0B4D 5E       01664         LD      E,(HL)          ;P/u PUTPTR & compare
0B4E 7B       01665         LD      A,E             ;GETPTR
0B4F 23       01666         INC     HL
0B50 BE       01667         CP      (HL)
0B51 2821     01668         JR      Z,$M8           ;Jump if key buffer empty
0B53 3A2C00   01669         LD      A,(TIMER$)      ;Check if we expired the
0B56 DD8603   01670         ADD     A,(IX+RPTRATE)  ;  time interval between
0B59 DDBE01   01671         CP      (IX+1)          ;  repeating keys
0B5C 2012     01672         JR      NZ,$M7          ;Go if time not up
0B5E DD8603   01673         ADD     A,(IX+RPTRATE)  ;Re-adjust time check so
0B61 DD7701   01674         LD      (IX+1),A        ;  we don't repeat in
0B64 C9       01675         RET                     ;  type-ahead task
              01676 ;
              01677 ;       CLEAR @ control key entered, clear the buffer
              01678 ;
0B65 23       01679 CLRTYP  INC     HL              ;Bump to PUT pointer
0B66 AF       01680 $M6     XOR     A
0B67 77       01681         LD      (HL),A          ;1st PUT is loc'n 0
0B68 23       01682         INC     HL              ;Pt to GETPTR
0B69 77       01683         LD      (HL),A          ;1st GET is loc'n 0
0B6A 217400   01684 R7KFLG  LD      HL,KFLAG$       ;Show buffer empty
0B6D CBBE     01685         RES     7,(HL)
0B6F C9       01686         RET
              01687 ;
              01688 ;       Char to stuff - check if buffer will overflow
              01689 ;
0B70 7B       01690 $M7     LD      A,E             ;P/u current PUT pointer
0B71 3C       01691         INC     A               ;If the next loc'n wraaps
0B72 BE       01692         CP      (HL)            ;  to the GET loc'n,
0B73 C8       01693         RET     Z               ;  don't permit overrun
0B74 E5       01694 $M8     PUSH    HL              ;Save ptr to GETPTR
0B75 23       01695         INC     HL              ;Pt to start of keybuf
0B76 1600     01696         LD      D,0             ;  & calculate PUT loc'n
0B78 19       01697         ADD     HL,DE
0B79 70       01698         LD      (HL),B          ;Store the char
0B7A 217400   01699         LD      HL,KFLAG$       ;Show type buffer
0B7D CBFE     01700         SET     7,(HL)          ;  is not empty
0B7F E1       01701         POP     HL              ;Rcvr ptr to GETPTR
0B80 2B       01702         DEC     HL              ;Backup to PUTPTR
0B81 34       01703         INC     (HL)            ;Bump past the char
0B82 3E50     01704         LD      A,80            ;Check for >80
0B84 BE       01705         CP      (HL)
0B85 D0       01706         RET     NC              ;Back if not over 80
0B86 72       01707         LD      (HL),D          ;  else reset to 1st
0B87 C9       01708         RET                     ;  position in buf (0)
              01709 ;
              01710 ;       Type ahead buffer area
              01711 ;
FF80          01712 TYPBUF  EQU     0FF80H
              01713 ;
              01714 ;       TYPBUF+0 = On/Off Flag
              01715 ;       TYPBUF+1 = Storage pointer
              01716 ;       TYPBUF+2 = Retrieve pointer
              01717 ;       TYPBUF+3 = Start of actual buffer
              01718 ;
0B87          01719 KILAST  EQU     $-1
              01720         ENDIF
              01721         IF      @GERMAN
              01722 FREN    EQU     00
              01723 GERM    EQU     -1
              01725         ENDIF
              01726         IF      @FRENCH
              01727 FREN    EQU     -1
              01728 GERM    EQU     00
              01730         ENDIF
0B88          01731 *GET    DODVR:3                 ;Video driver
              01732 ;DODVR/ASM - LS-DOS 6.2
              01735 *MOD
0084          01736 @OPREG  EQU     84H             ;Mem mgt & video control
0088          01737 CRTCADD EQU     88H             ;CRTC address port
0089          01738 CRTCDAT EQU     89H             ;CRTC data port
0050          01739 LINESIZ EQU     80
0018          01740 NUMROWS EQU     24
FFB0          01741 NEGLINE EQU     -LINESIZ
0780          01742 CRTSIZE EQU     LINESIZ*NUMROWS
0800          01743 RAMSIZE EQU     2048
F800          01744 CRTBGN$ EQU     0F800H
FF7F          01745 CRTEND  EQU     CRTBGN$+CRTSIZE-1
              01746 ;
              01747 ;       Driver entry point
              01748 ;
0B88 1812     01749 DODVR   JR      DOBGN           ;Branch around linkage
0B8A 000E     01750         DW      DOEND           ;Last memory location used
0B8C 03       01751         DB      3,'$DO'
     24 44 4F 
0B90 1002     01752         DW      DODCB$          ;DCB used
0B92 0000     01753         DW      0               ;Reserved
0B94          01754 DODATA$ EQU     $
0000          01755 DO_MASK EQU     $-DODATA$
0007          01756 SCRPROT EQU     7               ;Bits 0-2: scroll protect
0003          01757 TABS    EQU     3               ;Bit 3: 0=tabs, 1=chars
0004          01758 CTL     EQU     4               ;Bit 4, display controls
              01759         IF      @USA
0B94 00       01760         DB      0               ;Tab/Spec, Scroll protect
              01761         ENDIF
              01762         IF      @INTL
              01763         DB      08              ;Space compression off
              01764         ENDIF
0B95 00F8     01765 CURSOR  DW      CRTBGN$
0B97 20       01766 CRSAVE  DB      20H             ;Character under cursor
0B98 5F       01767 CRSCHAR DB      '_'             ;Cursor character
              01768 ;
              01769 ;       Entry from SVC 15, @VDCTL
              01770 ;
0B99 C3420D   01771 @VDCTL  JP      @_VDCTL
              01772 ;
              01773 ;       Continue regular driver functions
              01774 ;
0B9C DD21940B 01775 DOBGN   LD      IX,DODATA$
0BA0 CD1708   01776         CALL    ENADIS_DO_RAM   ;Bring up the video RAM
0BA3 DAB30D   01777         JP      C,$N0           ;Go on 'GET' request
0BA6 CDB30D   01778         CALL    $N0             ;Handle cursor
0BA9 C5       01779         PUSH    BC              ;Need to save C
0BAA 79       01780         LD      A,C             ;Get char to display
0BAB DDCB0066 01781         BIT     CTL,(IX+DO_MASK) ;Display controls set?
0BAF 2009     01782         JR      NZ,$N1A         ;Go if so
0BB1 B7       01783         OR      A               ;Char a 0?
0BB2 CA9F0C   01784         JP      Z,TGGLCTL       ;Switch Bit CTL if so
0BB5 FE20     01785         CP      20H             ;Video control char?
0BB7 DA440C   01786         JP      C,DO_CONTROL    ;Go if so
0BBA FEC0     01787 $N1A    CP      0C0H            ;Tab or special?
0BBC 3806     01788         JR      C,DONORM        ;Go on normal characters
              01789 ;
              01790 ;       Character is => 0C0H
              01791 ;
0BBE DDCB005E 01792         BIT     TABS,(IX+DO_MASK) ;Tabs or spec chars
0BC2 2826     01793         JR      Z,DO_TABS       ;Go if video tabs
              01794 ;
              01795 ;       Character is not tab expansion - do it
              01796 ;
0BC4 CDB80C   01797 DONORM  CALL    DO_DSPCHAR      ;Display the char
0BC7 DDCB00A6 01798         RES     CTL,(IX+DO_MASK) ;Turn off CTL bit
0BCB C1       01799 DO_RET  POP     BC              ;Get orig char
0BCC F3       01800 DO_RET1 DI                      ;Disable intr
0BCD 3A970B   01801         LD      A,(CRSAVE)      ;If a cursor is on, then
0BD0 B7       01802         OR      A               ;  we need to save the
0BD1 2810     01803         JR      Z,$N1           ;  current char & display
0BD3 1A       01804         LD      A,(DE)          ;  the cursor character
0BD4 32970B   01805         LD      (CRSAVE),A      ;Save current char
0BD7 3A7F00   01806         LD      A,(VFLAG$)      ;Allow tasker to blink
0BDA CBBF     01807         RES     7,A
0BDC 327F00   01808         LD      (VFLAG$),A
0BDF 3A980B   01809         LD      A,(CRSCHAR)     ;P/u cusor character
0BE2 12       01810         LD      (DE),A          ;Put it on the screen
0BE3 ED53950B 01811 $N1     LD      (CURSOR),DE     ;Update cursor position
0BE7 BF       01812         CP      A               ;Clear status
0BE8 79       01813         LD      A,C             ;Restore the char
0BE9 C9       01814         RET
              01815 ;
              01816 ;       Perform a tab expansion {C0H-FFH}
              01817 ;
              01818 DO_TABS
0BEA D6C0     01819         SUB     0C0H            ;Compute spaces
0BEC 28DD     01820         JR      Z,DO_RET        ;Forget it if TAB(0)
0BEE 47       01821         LD      B,A             ;Display requested
0BEF 0E20     01822 $N2     LD      C,' '           ;  number of spaces
0BF1 CDB80C   01823         CALL    DO_DSPCHAR
0BF4 10F9     01824         DJNZ    $N2
0BF6 18D3     01825         JR      DO_RET
              01826 ;
              01827 ;       Routine to move the cursor to begin of line {29}
              01828 ;
              01829 CRSBOL
0BF8 EB       01830         EX      DE,HL           ;Cursor addr to HL
0BF9 CDF40D   01831         CALL    ADDR1           ;Find row,col
0BFC 6F       01832         LD      L,A             ;Set col to start
0BFD C3D00D   01833         JP      ROWCOL_2_ADDR   ;Calc address of BOL
              01834 ;
              01835 ;       Routines to turn on/off the cursor {14/15}
              01836 ;
0C00 1A       01837 CRSON   LD      A,(DE)          ;Get screen character
0C01 32970B   01838 CRSOFF  LD      (CRSAVE),A      ;Save zero or CRT char
0C04 C9       01839         RET
              01840 ;
              01841 ;       Routine moves cursor to start of video page {28}
              01842 ;        set to 80 column, and turns off inverse video
              01843 ;
              01844 CRSHOME
0C05 1100F8   01845         LD      DE,CRTBGN$      ;Home the cursor
0C08 3A7600   01846         LD      A,(MODOUT$)     ;P/u the mask &
0C0B E6FB     01847         AND     0FBH            ;  set to 80 cpl
0C0D CDB20C   01848         CALL    SETMOD
0C10 187A     01849         JR      DO_INVERT_DIS   ;Set to normal video
              01850 ;
              01851 ;       Routine to backspace & erase cursor {08}
              01852 ;
              01853 BACKSPA
0C12 CD1B0C   01854         CALL    CRSBKSP         ;Backspace the cursor
0C15 C8       01855         RET     Z               ;If not at start,
0C16 0E20     01856         LD      C,' '           ;  put a space at
0C18 C3CA0D   01857         JP      PUT_@           ;  at the new loc'n
              01858 ;
              01859 ;       Routine to backspace the cursor {24}
              01860 ;
              01861 CRSBKSP
0C1B 3A7600   01862         LD      A,(MODOUT$)     ;If double width chars,
0C1E E604     01863         AND     4               ;  need to do twice
0C20 C4230C   01864         CALL    NZ,$+3
0C23 2100F8   01865         LD      HL,CRTBGN$      ;See if at home position
0C26 ED52     01866         SBC     HL,DE           ;  prior to adjusting
0C28 C8       01867         RET     Z
0C29 1B       01868         DEC     DE              ;Decrement the cursor pos
0C2A C9       01869         RET
              01870 ;
              01871 ;       Routine to move the cursor up one line {27}
              01872 ;
              01873 CRSUP
0C2B 21B0FF   01874         LD      HL,NEGLINE      ;Move up one line
0C2E 1803     01875         JR      MOVCRS
              01876 ;
              01877 ;       Routine to move the cursor down one line {26}
              01878 ;
              01879 CRSDOWN
0C30 215000   01880         LD      HL,LINESIZ      ;Add the line length
0C33 19       01881 MOVCRS  ADD     HL,DE           ;  to the current pos
0C34 7C       01882         LD      A,H             ;Make sure we did not
0C35 FEF8     01883         CP      CRTBGN$<-8      ;  go over the top
0C37 D8       01884         RET     C
0C38 EB       01885         EX      DE,HL           ;  & switch back to DE
0C39 1B       01886         DEC     DE              ;Adjust for fall thru
0C3A C3C30C   01887         JP      CRSFRW0
              01888 ;
              01889 ;       Set to 40 cpl mode {23}
              01890 ;
0C3D 3A7600   01891 SET40   LD      A,(MODOUT$)     ;Get image of the port
0C40 F604     01892         OR      04H             ;Merge in 40 cpl bit
0C42 186E     01893         JR      SETMOD
              01894 ;
              01895 ;       Routines to parse control functions
              01896 ;
              01897 DO_CONTROL
0C44 21CB0B   01898         LD      HL,DO_RET       ;Establish RET
0C47 E5       01899         PUSH    HL
0C48 FE08     01900         CP      08H             ;Backspace?
0C4A 28C6     01901         JR      Z,BACKSPA
0C4C FE0A     01902         CP      0AH             ;Line feed?
0C4E 2802     01903         JR      Z,$+4           ;  is same as 
0C50 D60D     01904         SUB     0DH             ;Carriage return?
0C52 CA020D   01905         JP      Z,LINFEED
0C55 3D       01906         DEC     A               ;Cursor on?
0C56 28A8     01907         JR      Z,CRSON
0C58 3D       01908         DEC     A               ;Cursor off?
0C59 28A6     01909         JR      Z,CRSOFF
0C5B 3D       01910         DEC     A               ;Reverse video?
0C5C 282B     01911         JR      Z,DO_INVERT_ENA
0C5E 3D       01912         DEC     A
0C5F 283A     01913         JR      Z,DO_INVERT_OFF
0C61 D604     01914         SUB     4               ;Swap tab/alternate?
0C63 2841     01915         JR      Z,TGGLTAB
0C65 3D       01916         DEC     A               ;Special/alternate?
0C66 2845     01917         JR      Z,TGGLALT
0C68 3D       01918         DEC     A               ;40 cpl?
0C69 28D2     01919         JR      Z,SET40
0C6B 3D       01920         DEC     A               ;Cursor backspace?
0C6C 28AD     01921         JR      Z,CRSBKSP
0C6E 3D       01922         DEC     A               ;Cursor forward?
0C6F 284A     01923         JR      Z,CRSFRWD
0C71 3D       01924         DEC     A               ;Cursor down?
0C72 28BC     01925         JR      Z,CRSDOWN
0C74 3D       01926         DEC     A               ;Cursor up?
0C75 28B4     01927         JR      Z,CRSUP
0C77 3D       01928         DEC     A               ;Cursor home?
0C78 CA050C   01929         JP      Z,CRSHOME
0C7B 3D       01930         DEC     A               ;Cursor BOL?
0C7C CAF80B   01931         JP      Z,CRSBOL
0C7F 3D       01932         DEC     A               ;Clear to EOL?
0C80 CA120D   01933         JP      Z,CLREOL
0C83 3D       01934         DEC     A
0C84 CA1E0D   01935         JP      Z,CLREOF        ;Clear to end-of-frame?
0C87 AF       01936         XOR     A               ;Clear A reg.
0C88 C9       01937         RET
              01938 ;
              01939 ;       Routine to enable inverse video
              01940 ;
              01941 DO_INVERT_ENA
0C89 0608     01942         LD      B,8             ;Set for enable
0C8B 21       01943         DB      21H             ;Ignore next load
              01944 DO_INVERT_DIS
0C8C 0600     01945         LD      B,0
0C8E 2A3508   01946         LD      HL,(OPREG_SV_PTR)       ;Real OPREG$
0C91 7E       01947         LD      A,(HL)          ;P/u OPREG mask
0C92 E6F7     01948         AND     0F7H            ;Strip bit 3
0C94 B0       01949         OR      B               ;Set/reset invideo bit
0C95 77       01950         LD      (HL),A          ;  and restuff
0C96 78       01951         LD      A,B             ;Get mode mask byte
0C97 07       01952         RLCA                    ;Rotate left 4 times to
0C98 07       01953         RLCA                    ;  make an 8 into 80H
0C99 07       01954         RLCA                    ;  for inverse on
0C9A 07       01955         RLCA                    ;Inverse off remains 0
              01956 DO_INVERT_OFF
0C9B 32CB0D   01957         LD      (INVIDEO),A     ;Set the mask byte
0C9E C9       01958         RET
              01959 ;
              01960 ;       Routine to toggle display of controls
              01961 ;
0C9F 21CB0B   01962 TGGLCTL LD      HL,DO_RET       ;Establish ret addr
0CA2 E5       01963         PUSH    HL
0CA3 3E10     01964         LD      A,10H           ;Toggle bit 4
0CA5 21       01965         DB      21H             ;Ignore next
              01966 ;
              01967 ;       Toggle tabs & alternate character set
              01968 ;
              01969 TGGLTAB
0CA6 3E08     01970         LD      A,8             ;Toggle bit 3
0CA8 DDAE00   01971         XOR     (IX+DO_MASK)    ;P/u mask value
0CAB 1850     01972         JR      SETMASK
              01973 ;
              01974 ;       Toggle special & alternate character set
              01975 ;
              01976 TGGLALT
0CAD 3A7600   01977         LD      A,(MODOUT$)     ;P/u port mask
0CB0 EE08     01978         XOR     8               ;Flip the bit
0CB2 327600   01979 SETMOD  LD      (MODOUT$),A     ;Resave port mask
0CB5 D3EC     01980         OUT     (0ECH),A        ;  and send the byte
0CB7 C9       01981         RET
              01982 ;
              01983 ;       Display character  at current cursor position
              01984 ;
              01985 DO_DSPCHAR
0CB8 CDCA0D   01986         CALL    PUT_@           ;Display the char
              01987 ;
              01988 ;       Routine to perform cursor forward {25}
              01989 ;
              01990 CRSFRWD
0CBB 3A7600   01991         LD      A,(MODOUT$)     ;If double width chars,
0CBE E604     01992         AND     4               ;  need to do twice
0CC0 2801     01993         JR      Z,CRSFRW0
0CC2 13       01994         INC     DE              ;Move cursor forward
0CC3 13       01995 CRSFRW0 INC     DE
0CC4 217FFF   01996         LD      HL,CRTEND       ;Off the screen?
0CC7 ED52     01997         SBC     HL,DE
0CC9 D0       01998         RET     NC              ;Back if not
0CCA CD2B0C   01999         CALL    CRSUP           ;Put cursor back on
0CCD D5       02000         PUSH    DE              ;Save cursor position
              02001 DO_SCROLL
0CCE DD7E00   02002         LD      A,(IX+DO_MASK)  ;Get scroll protect
0CD1 E607     02003         AND     SCRPROT
0CD3 2100F8   02004         LD      HL,CRTBGN$      ;Point to CRT start
0CD6 118007   02005         LD      DE,CRTSIZE      ;P/u CRT size
0CD9 C5       02006         PUSH    BC
0CDA 015000   02007         LD      BC,LINESIZ      ;Set line size
0CDD 3C       02008         INC     A               ;Adjust scroll protect
0CDE 09       02009 $N4     ADD     HL,BC           ;Move logical start
0CDF EB       02010         EX      DE,HL           ;  down one line
0CE0 B7       02011         OR      A               ;  and subtract one line
0CE1 ED42     02012         SBC     HL,BC           ;  from the CRTSIZE for
0CE3 EB       02013         EX      DE,HL           ;  each protected line
0CE4 3D       02014         DEC     A               ;Dec scroll protect
0CE5 20F7     02015         JR      NZ,$N4          ;Loop until done
0CE7 D5       02016         PUSH    DE              ;Save the move length
0CE8 E5       02017         PUSH    HL              ;Save the move-from
0CE9 ED42     02018         SBC     HL,BC           ;Move start back one
0CEB EB       02019         EX      DE,HL           ;  line, Source =
0CEC E1       02020         POP     HL              ;  start + one
0CED C1       02021         POP     BC              ;Get back dest locn
0CEE EDB0     02022         LDIR                    ;Scroll unprotected
0CF0 C1       02023         POP     BC              ;Recover line size
0CF1 182C     02024         JR      CLREOF1         ;Clear to EOF from DE
              02025 ;
              02026 ;       Set scroll protect value
              02027 ;               C = scroll protect <0-7>
              02028 ;               B = 7
              02029 ;               SVC = 15, @VDCTL
              02030 ;
              02031 SET_SCROLL
0CF3 79       02032         LD      A,C             ;Get user value
0CF4 E607     02033         AND     7               ;Make modulo 8
0CF6 4F       02034         LD      C,A
0CF7 3A940B   02035         LD      A,(DODATA$)     ;P/u current mask
0CFA E6F8     02036         AND     0F8H            ;Remove current scroll
0CFC B1       02037         OR      C               ;Merge in the new value
0CFD 32940B   02038 SETMASK LD      (DODATA$),A     ;  & reload mask
0D00 AF       02039         XOR     A               ;Z-flag return
0D01 C9       02040         RET
              02041 ;
              02042 ;       Routine to move down one line {10/13}
              02043 ;
0D02 CDF80B   02044 LINFEED CALL    CRSBOL          ;Move to BOL
0D05 D5       02045         PUSH    DE              ;Save cursor position
0D06 CD300C   02046         CALL    CRSDOWN         ;Move down one line
0D09 B7       02047         OR      A               ;Reset the carry flag
0D0A 2180FF   02048         LD      HL,CRTEND+1     ;  & check if off of
0D0D ED52     02049         SBC     HL,DE           ;  the screen
0D0F 28BD     02050         JR      Z,DO_SCROLL     ;Scroll if so
0D11 E1       02051         POP     HL              ;Discard old position
0D12 D5       02052 CLREOL  PUSH    DE              ;Save new cursor pos
0D13 CDF80B   02053         CALL    CRSBOL          ;Get start of line
0D16 214F00   02054         LD      HL,79           ;Calculate end of line
0D19 19       02055         ADD     HL,DE           ;HL = end of line
0D1A D1       02056         POP     DE              ;DE = current position
0D1B D5       02057         PUSH    DE
0D1C 1804     02058         JR      CLREOF2         ;Clear the line
              02059 ;
              02060 ;       Clear to the end of the frame
              02061 ;
0D1E D5       02062 CLREOF  PUSH    DE              ;Save current cursor pos
0D1F 217FFF   02063 CLREOF1 LD      HL,CRTEND       ;Point to last RAM byte
0D22 3ACB0D   02064 CLREOF2 LD      A,(INVIDEO)     ;P/u normal/reverse
0D25 CBEF     02065         SET     5,A             ;  & make it a space
0D27 12       02066         LD      (DE),A          ;Stuff the "space"
0D28 B7       02067         OR      A               ;Reset carry for subtract
0D29 ED52     02068         SBC     HL,DE           ;Calculate length
0D2B 2809     02069         JR      Z,CLREOF3       ;Back if at end already
0D2D C5       02070         PUSH    BC
0D2E 44       02071         LD      B,H             ;Xfer length to BC
0D2F 4D       02072         LD      C,L
0D30 62       02073         LD      H,D             ;Xfer start to HL
0D31 6B       02074         LD      L,E
0D32 13       02075         INC     DE              ;Bump up by one
0D33 EDB0     02076         LDIR                    ;Propagate the space
0D35 C1       02077         POP     BC
0D36 D1       02078 CLREOF3 POP     DE
0D37 C9       02079         RET
              02080 ;
              02081 ;       Routine to stuff the video cursor RAM address
              02082 ;
0D38 CDD00D   02083 @VDCTL3 CALL    ROWCOL_2_ADDR   ;Calculate video address
0D3B C0       02084         RET     NZ              ;Back on error
0D3C F3       02085         DI                      ;Disable any video tasks
0D3D ED53950B 02086         LD      (CURSOR),DE     ;  until cursor is updated
0D41 C9       02087         RET
              02088 ;
              02089 ;       Video control SVC processor
              02090 ;
              02091 @_VDCTL
0D42 CD1708   02092         CALL    ENADIS_DO_RAM   ;Bring up the video RAM
              02093 ;
              02094 ;       Test if in Task processor
              02095 ;
0D45 3A7700   02096         LD      A,(NFLAG$)      ;P/u NFLAG$
0D48 CB77     02097         BIT     6,A             ;Test for task process
0D4A 2015     02098         JR      NZ,VDCTL        ;If so skip setup
              02099 ;
              02100 ;       HANDLES @VDCTL screen set up for normal use
              02101 ;
0D4C D5       02102         PUSH    DE
0D4D CDB30D   02103         CALL    $N0             ;Normalize character at cursor
0D50 D1       02104         POP     DE              ;Recover value
0D51 D5       02105         PUSH    DE
0D52 CD610D   02106         CALL    VDCTL           ;Do function request
0D55 F5       02107         PUSH    AF              ;Save the error status
0D56 F3       02108         DI                      ;Stop video tasks tempy
0D57 ED5B950B 02109         LD      DE,(CURSOR)
0D5B CDCC0B   02110         CALL    DO_RET1         ;Normalize screen and cursor
0D5E F1       02111         POP     AF
0D5F D1       02112         POP     DE
0D60 C9       02113         RET
              02114 ;
0D61 3E09     02115 VDCTL   LD      A,9             ;Check for VIDLINE,
0D63 B8       02116         CP      B               ;  function 9
0D64 2825     02117         JR      Z,VIDLIN
0D66 3E2B     02118         LD      A,43            ;Prepare for user ERROR
0D68 05       02119         DEC     B
0D69 2843     02120         JR      Z,GET_@_ROWCOL  ; from row-H, col-L
0D6B 05       02121         DEC     B
0D6C 2858     02122         JR      Z,PUT_@_ROWCOL  ; to row-H, col-L
0D6E 05       02123         DEC     B
0D6F 28C7     02124         JR      Z,@VDCTL3       ;Set cursor to H,L
0D71 05       02125         DEC     B
0D72 287D     02126         JR      Z,ADDR_2_ROWCOL ;Cursor row,col to H,L
0D74 1100F8   02127         LD      DE,CRTBGN$      ;Init to start of video
0D77 05       02128         DEC     B
0D78 282D     02129         JR      Z,VIDMOV1       ;User RAM to video
0D7A 05       02130         DEC     B
0D7B 2822     02131         JR      Z,VIDMOVE       ;Video RAM to user
0D7D 05       02132         DEC     B
0D7E CAF30C   02133         JP      Z,SET_SCROLL    ;Set scroll protect
0D81 05       02134         DEC     B
0D82 C0       02135         RET     NZ              ;Return if bad request
              02136 ;
              02137 ;       Establish cursor character
              02138 ;
0D83 E5       02139         PUSH    HL
0D84 21980B   02140         LD      HL,CRSCHAR      ;Point to cursor char storage
0D87 7E       02141         LD      A,(HL)          ;P/u current cursor character
0D88 71       02142         LD      (HL),C          ;  & update with new one
0D89 E1       02143         POP     HL
0D8A C9       02144         RET
              02145 ;
              02146 ;       VIDLIN routine function - 9 in register B
              02147 ;
0D8B 2E00     02148 VIDLIN  LD      L,0             ;Always starts at col 0
0D8D D5       02149         PUSH    DE              ;Save user buffer
0D8E CDD00D   02150         CALL    ROWCOL_2_ADDR   ;Get address to DE
0D91 E1       02151         POP     HL              ;Recover user buffer
0D92 C0       02152         RET     NZ              ;Quit on bad address
0D93 0C       02153         INC     C               ;Check direction
0D94 0D       02154         DEC     C               ;If Z then to screen
0D95 2801     02155         JR      Z,MOVLIN        ;Set to go
0D97 EB       02156         EX      DE,HL           ;Reverse direction
0D98 015000   02157 MOVLIN  LD      BC,LINESIZ      ;Set line size
0D9B EDB0     02158         LDIR                    ;Move it
0D9D AF       02159         XOR     A               ;Z on RET
0D9E C9       02160         RET
              02161 ;
              02162 ;       Routine to move video RAM
              02163 ;
0D9F 7C       02164 VIDMOVE LD      A,H             ;Check on user buffer
0DA0 C608     02165         ADD     A,8             ;  not above X'F800' &
0DA2 FE2C     02166         CP      24H+8           ;  not below X'2400'
0DA4 3847     02167         JR      C,PERR
0DA6 EB       02168         EX      DE,HL           ;Xchng user buffer,screen
0DA7 018007   02169 VIDMOV1 LD      BC,CRTSIZE      ;Set for full screen xfer
0DAA EDB0     02170         LDIR
0DAC BF       02171         CP      A               ;Set Z flag
0DAD C9       02172         RET
              02173 ;
              02174 ;       Routine to get the character at row,col
              02175 ;
              02176 GET_@_ROWCOL
0DAE CDD00D   02177         CALL    ROWCOL_2_ADDR   ;Get Address of req
0DB1 1A       02178         LD      A,(DE)          ;P/u the character
0DB2 C9       02179         RET                     ;Back on error or no error
              02180 ;
              02181 ;       Routine to halt blinking cursor & restore char
              02182 ;
0DB3 E5       02183 $N0     PUSH    HL
0DB4 217F00   02184         LD      HL,VFLAG$
0DB7 CBFE     02185         SET     7,(HL)          ;Disable blinking cursor
0DB9 E1       02186         POP     HL
0DBA ED5B950B 02187         LD      DE,(CURSOR)     ;Get cursor pos in DE
0DBE 3A970B   02188         LD      A,(CRSAVE)      ;P/u saved character
0DC1 B7       02189         OR      A               ;If one is saved, put
              02190                                 ;  it on screen, else
0DC2 2009     02191         JR      NZ,PUTA@DE      ;  ignore it
0DC4 1A       02192         LD      A,(DE)          ;Cursor not ON but get
0DC5 C9       02193         RET                     ;  character anyway
              02194 ;
              02195 ;       Routine to put a character at row,col
              02196 ;
              02197 PUT_@_ROWCOL
0DC6 CDD00D   02198         CALL    ROWCOL_2_ADDR   ;Get address of req
0DC9 C0       02199         RET     NZ              ;Back on error
0DCA 3E00     02200 PUT_@   LD      A,0             ;Merge in reverse video
0DCB          02201 INVIDEO EQU     $-1
0DCC B1       02202         OR      C
0DCD 12       02203 PUTA@DE LD      (DE),A          ;Put the character
0DCE BF       02204         CP      A               ;Set Z-flag for return
0DCF C9       02205         RET
              02206 ;
              02207 ;       Routine to calculate cursor position from row,col
              02208 ;
              02209 ROWCOL_2_ADDR
0DD0 3E4F     02210         LD      A,79
0DD2 BD       02211         CP      L
0DD3 3818     02212         JR      C,PERR          ;Error if > 79
0DD5 7C       02213         LD      A,H             ;P/u row number
0DD6 FE18     02214         CP      24
0DD8 3013     02215         JR      NC,PERR         ;Error if > 23
0DDA E5       02216         PUSH    HL
0DDB C5       02217         PUSH    BC
0DDC 4D       02218         LD      C,L             ;Save column
0DDD 06F8     02219         LD      B,CRTBGN$<-8    ;Set to start of DO RAM
0DDF 215000   02220         LD      HL,LINESIZ
0DE2 CDC906   02221         CALL    @MUL16          ;Rows * line size
0DE5 65       02222         LD      H,L             ;Shift to HL
0DE6 6F       02223         LD      L,A
0DE7 09       02224         ADD     HL,BC           ;Add in col & RAM start
0DE8 EB       02225         EX      DE,HL           ;Address to DE
0DE9 C1       02226         POP     BC
0DEA E1       02227         POP     HL
0DEB AF       02228         XOR     A               ;Set Z flag
0DEC C9       02229         RET
0DED 3E2B     02230 PERR    LD      A,43            ;SVC parameter error
0DEF B7       02231         OR      A               ;Set NZ condition
0DF0 C9       02232         RET
              02233 ;
              02234 ;       Routine to get row,col of video cursor
              02235 ;
              02236 ADDR_2_ROWCOL
0DF1 2A950B   02237         LD      HL,(CURSOR)     ;Get addr in HL
0DF4 7C       02238 ADDR1   LD      A,H             ;Make address relative
0DF5 E607     02239         AND     7               ;  to origin 0
0DF7 67       02240         LD      H,A
0DF8 3E50     02241         LD      A,LINESIZ       ;Set divisor
0DFA CDE306   02242         CALL    @DIV16
0DFD 65       02243         LD      H,L             ;Row to register H
0DFE 6F       02244         LD      L,A             ;Column to register L
0DFF AF       02245         XOR     A               ;Set zero return code
0E00 C9       02246         RET
0E00          02247 DOEND   EQU     $-1
0E01          02249 *GET    PRDVR:3                 ;Printer driver & filter
              02250 ;PRDVR/ASM - LS-DOS 6.2
              02253 *MOD
00F8          02254 PRPORT  EQU     0F8H
              02255 ;
              02256 ;       PR driver entry point
              02257 ;       It passes X'00'-X'FF'
              02258 ;       Unless INTL version
              02259 ;
0E01 180A     02260 PRDVR   JR      PRBGN           ;Branch around linkage
0E03 3C0E     02261         DW      PREND           ;Last byte used
0E05 03       02262         DB      3,'$PR'
     24 50 52 
0E09 1802     02263         DW      PRDCB$          ;Pointer to its DCB
0E0B 0000     02264         DW      0               ;Reserved
              02265 ;
              02266 ;       Driver code
              02267 ;
0E0D 280A     02268 PRBGN   JR      Z,$O2           ;Go if output
0E0F 3804     02269         JR      C,$O1           ;Go if input req
              02270 ;
              02271 ;       Character CTL request
              02272 ;
0E11 79       02273         LD      A,C             ;If CTL 0, return
0E12 B7       02274         OR      A               ;  status else
0E13 2821     02275         JR      Z,$O4           ;  treat as a Get
              02276 ;
              02277 ;       Character GET request
              02278 ;
0E15 F6FF     02279 $O1     OR      0FFH            ;Set nz
0E17 2F       02280         CPL                     ;  & A=0        to show
0E18 C9       02281         RET                     ;  no char available
              02282 ;
              02283 ;       Character PUT request
              02284 ;
0E19 11FFFF   02285 $O2     LD      DE,0FFFFH       ;Check status 2000 times
0E1C CD360E   02286 $O2A    CALL    $O4             ;PR ready?
0E1F 2811     02287         JR      Z,$O3           ;Go if so
              02288 ;
              02289 ;       Ten second timout delay loop
              02290 ;
0E21 C5       02291         PUSH    BC              ;Printer was not ready
0E22 010800   02292         LD      BC,8
0E25 CD8203   02293         CALL    PAUSE@          ;Delay a bit
0E28 C1       02294         POP     BC
              02295         IF      @BLD631
0E29 1B       02296 @PRTIMO:DEC     DE              ;<631>SYSTEM cmd patches this addr
              02297         ELSE
              02298         DEC     DE              ;Time up?
              02299         ENDIF
0E2A 7A       02300         LD      A,D
0E2B B3       02301         OR      E
0E2C 20EE     02302         JR      NZ,$O2A         ;Nope, continue check
0E2E 3E08     02303         LD      A,8             ;Device not avail...
0E30 B7       02304         OR      A               ;Set NZ condition
0E31 C9       02305         RET
0E32          02306 $O3     EQU     $
              02307 ;
              02308         IF      @INTL
              02309         LD      A,(IFLAG$)
              02310         BIT     6,A             ;Special DMP PR?
              02311         ENDIF
              02312 ;
0E32 79       02313         LD      A,C
              02314 ;
              02315         IF      @INTL
              02316         JR      Z,PVAL3
              02317         CP      0C0H            ;Values C0-FF (-20H)
              02318         JR      C,PVAL2         ;Go if less
              02319         SUB     20H             ;Shift to European chars
              02320         JR      PVAL3
              02321 PVAL2   CP      0A0H            ;A0-BF (+40H)
              02322         JR      C,PVAL3         ;Go if less
              02323         ADD     A,40H           ;Shift to graphics
              02324         ENDIF
              02325 ;
0E33 D3F8     02326 PVAL3   OUT     (PRPORT),A      ;Put out char
              02327 ;
              02328         IF      @INTL
              02329         LD      A,C             ;Restore original
              02330         CP      A               ;Set Z
              02331         ENDIF
              02332 ;
0E35 C9       02333         RET
              02334 ;
0E36 DBF8     02335 $O4     IN      A,(PRPORT)      ;Scan PR status
0E38 E6F0     02336         AND     0F0H            ;Mask unused positions
0E3A FE30     02337         CP      30H             ;PR ready?
0E3C C9       02338         RET                     ;Return with answer
0E3C          02339 PREND   EQU     $-1
0E3D          02340 *GET    FDCDVR:3                ;Floppy disk driver
              02341 ;FDCDVR/ASM - LS-DOS 6.2
              02344 ;
              02345 ;        HL=> buffer address
              02346 ;         D=> track desired
              02347 ;         E=> sector desired
              02348 ;         C=> drive desired
              02349 ;         B=> disk primitive command
              02350 ;
00E4          02351 WRNMIPORT       EQU     0E4H    ;NMI mask register
00F0          02352 FDCADR          EQU     0F0H    ;FDC command
00F0          02353 FDCSTAT         EQU     0F0H    ;FDC status
00F1          02354 TRKREG          EQU     0F1H    ;FDC track register
00F2          02355 SECREG          EQU     0F2H    ;FDC sector register
00F3          02356 DATREG          EQU     0F3H    ;FDC data register
00F4          02357 DSELCT          EQU     0F4H    ;Drive select port
              02358 ;
              02359 ;
              02360 ;       Disk Driver Entry Point
              02361 ;
0E3D 184F     02362 FDCDVR  JR      FDCBGN          ;Branch to entry code
0E3F F30F     02363         DW      FDCEND          ;Last byte used
0E41 03       02364         DB      3,'$FD'         ;Module name
     24 46 44 
              02365 ;
              02366 ;       Automatic density recognition and retry density switch
              02367 ;
              02368 SWDEN
0E45 3E03     02369         LD      A,3             ;Check counter for 2
0E47 B8       02370         CP      B               ;  tries left after this one
0E48 285E     02371         JR      Z,RESTOR        ;If so try a RESTORE
              02372 ;
0E4A FD7E03   02373         LD      A,(IY+3)        ;Flip the density bit,
0E4D EE40     02374         XOR     40H             ;  Bit 6, (IY+3)
0E4F FD7703   02375         LD      (IY+3),A
0E52 010924   02376         LD      BC,2409H        ;Set alloc to SDEN
0E55 CB77     02377         BIT     6,A             ;Test SDEN/DDEN
0E57 2803     02378         JR      Z,SDEN          ;Do SDEN if it was DDEN
0E59 011145   02379         LD      BC,4511H        ;  else set alloc to DDEN
0E5C FD7107   02380 SDEN    LD      (IY+7),C
0E5F FD7008   02381         LD      (IY+8),B
0E62 C9       02382         RET
              02383 ;
              02384 ;       Verify routine
              02385 ;
0E63 21E80F   02386 VERFIN  LD      HL,BUCKET       ;Set byte bucket
0E66 3E2D     02387         LD      A,2DH           ;Set for DEC L,...
0E68 1E       02388         DB      1EH             ;Ignore next with LD E,n
              02389 ;
              02390 ;       Read routine
              02391 ;
0E69 AF       02392 RDIN    XOR     A               ;Set for NOP
0E6A 327D0E   02393         LD      (CKVER),A
0E6D CD2B0F   02394         CALL    RWINIT          ;Initialize
0E70 1E16     02395         LD      E,16H           ;Status mask
0E72 DBF0     02396 RDIN1   IN      A,(FDCSTAT)     ;Get status
0E74 A3       02397         AND     E               ;Loop until DRQ
0E75 28FB     02398         JR      Z,RDIN1         ;  or error
0E77 EDA2     02399         INI                     ;Grab byte
0E79 F3       02400         DI
0E7A 7A       02401         LD      A,D             ;Get drive sel + WSGEN
0E7B D3F4     02402 RDIN2   OUT     (DSELCT),A      ;Initiate wait state
0E7D 00       02403 CKVER   NOP                     ;DEC L: if verify
0E7E EDA2     02404         INI                     ;Xfer byte
0E80 20F9     02405         JR      NZ,RDIN2        ;Loop then TSTBSY
              02406 ;
              02407 ;       Reselect drive while controller is busy
              02408 ;
0E82 DBF0     02409 TSTBSY  IN      A,(FDCSTAT)     ;Ck FDC status
0E84 CB47     02410         BIT     0,A             ;Busy?
0E86 C8       02411         RET     Z               ;RET if not
0E87 3A1B00   02412         LD      A,(PDRV$)       ;P/u drive
0E8A D3F4     02413         OUT     (DSELCT),A      ;  & reselect
0E8C 18F4     02414         JR      TSTBSY          ;Loop until idle
              02415 ;
              02416 ;       Driver start
              02417 ;
0E8E 78       02418 FDCBGN  LD      A,B             ;P/u primitive request
0E8F A7       02419         AND     A               ;NOP?
0E90 C8       02420         RET     Z               ;Quit if so
0E91 FE07     02421         CP      7
0E93 28ED     02422         JR      Z,TSTBSY        ;Jump on TSTBSY request
0E95 D2440F   02423         JP      NC,IORQST       ;Jump on I/O request
0E98 FE06     02424         CP      6
0E9A 284C     02425         JR      Z,SEEKTRK       ;Jump on track seek
0E9C 3D       02426         DEC     A
0E9D 2811     02427         JR      Z,SELECT        ;Jump on drive select
0E9F FD3405   02428         INC     (IY+5)          ;Bump current cylinder
0EA2 FE04     02429         CP      4
0EA4 0658     02430         LD      B,58H           ;FDC step-in command
0EA6 2872     02431         JR      Z,STEPIN
0EA8 FD360500 02432 RESTOR  LD      (IY+5),0        ;Set track to 0
0EAC 0608     02433         LD      B,8             ;Restore drive
0EAE 186A     02434         JR      STEPIN
              02435 ;
0EB0 CD820E   02436 SELECT  CALL    TSTBSY          ;Check drive status
0EB3 07       02437         RLCA
              02438         IF      @BLD631
              02439 ;
              02440 ;       This is the first part of the fix for Gate-Array systems.  Provided
              02441 ;       by Frank Durda IV in a paper for The Misosys Quarterly, Vol IV.iii
              02442 ;       Essentially, the motor-on timer in gate-array Model 4/4D/4P systems
              02443 ;       sometimes fails to log a write to 0xD4, and the motor can unexpectedly
              02444 ;       spin-down.  The most common symptom is to end up with duplicate
              02445 ;       directory entries.   The patch ensures that for directory accesses
              02446 ;       port 0xd4 is accessed twice before read/write operations begin.
              02447 ;
0EB4 FD7E03   02448         LD      A,(IY+3)        ;<631>P/u SDEN/DDEN/DELAY (DLY chked later)
0EB7 F5       02449         PUSH    AF              ;<631>Save NOT READY flag
0EB8 C5       02450         PUSH    BC              ;<631>
              02451         ELSE
              02452         PUSH    AF              ;Save NOT READY flag
              02453         PUSH    BC
              02454         LD      A,(IY+3)        ;P/u SDEN/DDEN
              02455         ENDIF
0EB9 17       02456         RLA                     ;Bit 6=>7, bit 4=>4
0EBA CB2F     02457         SRA     A
0EBC E690     02458         AND     90H             ;Keep only DDEN & side 1
0EBE 4F       02459         LD      C,A             ;Save the bits
0EBF CB7F     02460         BIT     7,A             ;Check if SDEN or DDEN
0EC1 2808     02461         JR      Z,NOPCMP        ;No precomp if SDEN
0EC3 FD7E09   02462         LD      A,(IY+9)        ;Set precomp on all
0EC6 BA       02463         CP      D               ;  tracks above DIR
0EC7 3002     02464         JR      NC,NOPCMP       ;Go if no precomp needed
0EC9 CBE9     02465         SET     5,C             ;Request precomp
0ECB FD7E04   02466 NOPCMP  LD      A,(IY+4)        ;Get drive sel code
0ECE E60F     02467         AND     0FH             ;Keep only sel bits
0ED0 B1       02468         OR      C               ;Merge in bits 4,5,7
0ED1 C1       02469         POP     BC
0ED2 D3F4     02470         OUT     (DSELCT),A      ;Select drive
0ED4 321B00   02471         LD      (PDRV$),A       ;Store port byte
              02472         IF      @BLD631
              02473 ;       This is the second part of the fix for Gate-Array systems.  Provided
              02474 ;       by Frank Durda IV in a paper for The Misosys Quarterly, Vol IV.iii
0ED7 D3F4     02475         OUT     (DSELCT),A      ;<631>Re-write Drive select just in case
0ED9 F1       02476         POP     AF              ;<631>Retrieve Not Ready Bit
0EDA D0       02477         RET     NC              ;<631>Return if was ready
0EDB CB57     02478         BIT     2,A             ;<631>Check DELAY=0.5 or 1.0 (IY+3 in A)
              02479         ELSE
              02480         POP     AF              ;Retrieve Not Ready bit
              02481         RET     NC              ;Ret if was ready
              02482         BIT     2,(IY+3)        ;Check DELAY=0.5 or 1.0
              02483         ENDIF
0EDD CCE00E   02484         CALL    Z,FDCDLY        ;Double delay if 1.0
0EE0 C5       02485 FDCDLY  PUSH    BC              ;Delay routine
0EE1 067F     02486         LD      B,7FH
0EE3 CD8203   02487         CALL    PAUSE@
0EE6 C1       02488         POP     BC
0EE7 C9       02489         RET
              02490 ;
              02491 ;       Routine to seek a track
              02492 ;
0EE8 CD820E   02493 SEEKTRK CALL    TSTBSY          ;Wait till not busy
0EEB FD7E05   02494         LD      A,(IY+5)        ;P/u current cylinder
0EEE D3F1     02495         OUT     (TRKREG),A      ;  & set FDC to current
0EF0 FD7E07   02496         LD      A,(IY+7)        ;P/u alloc data
0EF3 E61F     02497         AND     1FH             ;Get highest # sector
0EF5 93       02498         SUB     E               ;Form req sector minus
0EF6 2F       02499         CPL                     ;  max, setting CY flag if
0EF7 FDCB03A6 02500         RES     4,(IY+3)        ;  init side select to 0
0EFB 300B     02501         JR      NC,SETSECT      ;Go if sector on side 0
0EFD FDCB046E 02502         BIT     5,(IY+4)        ;If not 2-sided media,
0F01 2806     02503         JR      Z,FRCSID0       ;  don't set side 1
0F03 FDCB03E6 02504         SET     4,(IY+3)        ;Set side 1
0F07 06       02505         DB      06H             ;Ignore next with LD B,n
0F08 7B       02506 SETSECT LD      A,E             ;Restore unaltered sec #
0F09 D3F2     02507 FRCSID0 OUT     (SECREG),A      ;Set sector
0F0B 7A       02508         LD      A,D
0F0C D3F3     02509         OUT     (DATREG),A      ;Set desired track
0F0E FDBE05   02510         CP      (IY+5)          ;If at desired track,
0F11 0618     02511         LD      B,18H           ;  use seek, else use
0F13 2805     02512         JR      Z,STEPIN        ;  seek w/verify
0F15 FD7205   02513         LD      (IY+5),D        ;Update current cylinder
0F18 061C     02514         LD      B,1CH           ;Seek w/verify ocmmand
0F1A CDB00E   02515 STEPIN  CALL    SELECT          ;Select drive
0F1D FD7E03   02516         LD      A,(IY+3)
0F20 E603     02517         AND     3               ;Strip all but step rate
0F22 B0       02518         OR      B
0F23 D3F0     02519 PASSCMD OUT     (FDCADR),A      ;Give FDC its command
0F25 0612     02520         LD      B,12H
0F27 10FE     02521         DJNZ    $               ;Wait
0F29 AF       02522         XOR     A
0F2A C9       02523 FDCRET  RET
              02524 ;
              02525 ;       Read and write init routines
              02526 ;
0F2B 7A       02527 RWINIT  LD      A,D             ;Restuff trk reg
0F2C D3F1     02528         OUT     (TRKREG),A
0F2E 3A1B00   02529         LD      A,(PDRV$)       ;Get select code
0F31 F640     02530         OR      40H             ;Set WSGEN bit
0F33 57       02531         LD      D,A             ;Save code in D
0F34 E610     02532         AND     10H             ;Get side sel bit
0F36 0F       02533         RRCA                    ;  to bit 3
0F37 CB49     02534         BIT     1,C             ;Check if doing side cmp
0F39 2001     02535         JR      NZ,GETCMD       ;Go if so
0F3B AF       02536         XOR     A
0F3C B1       02537 GETCMD  OR      C
0F3D 0EF3     02538         LD      C,DATREG        ;Get port into C
0F3F CD0E00   02539         CALL    FDDINT$         ;Interrupts on or off?
0F42 18DF     02540         JR      PASSCMD         ;Pass command to ctrlr
              02541 ;
              02542 ;       I/O request handler
              02543 ;
0F44 CB50     02544 IORQST  BIT     2,B             ;Write command?
0F46 ED4B7A00 02545         LD      BC,(RFLAG$-1)   ;P/u retry count
0F4A 0E82     02546         LD      C,82H           ;FDC cmd=readsec
0F4C 2010     02547         JR      NZ,WRCMD        ;Go if write command
0F4E FE0A     02548         CP      10              ;Verify sector?
0F50 2806     02549         JR      Z,VERFY
0F52 CD790F   02550         CALL    GRABNDO         ;Grab next code & insert
0F55 01       02551         DB      1               ;Error code start
0F56 690E     02552         DW      RDIN            ;Read entry point
0F58 CD790F   02553 VERFY   CALL    GRABNDO         ;Stuff I/O direction
0F5B 01       02554         DB      1               ;Error code start
0F5C 630E     02555         DW      VERFIN          ;Verify entry point
0F5E FDCB037E 02556 WRCMD   BIT     7,(IY+3)        ;Software WP?
0F62 2803     02557         JR      Z,WRCMD1        ;Bypass if not
0F64 3E0F     02558         LD      A,15            ;Else set WP error
0F66 C9       02559         RET
0F67 0EA2     02560 WRCMD1  LD      C,0A2H          ;Write sector FDC command
0F69 FE0E     02561         CP      14              ;Directory sector?
0F6B 3806     02562         JR      C,DOWRIT
0F6D 0EA3     02563         LD      C,0A3H          ;Change DAM if directory
0F6F 2802     02564         JR      Z,DOWRIT
0F71 0EF0     02565         LD      C,0F0H          ;  else write track
0F73 CD790F   02566 DOWRIT  CALL    GRABNDO         ;Switch code
0F76 09       02567         DB      9               ;Error code start
0F77 BC0F     02568         DW      WROUT           ;Write entry point
              02569 ;
              02570 ;       Routine stuffs error start byte & I/O vector
              02571 ;
0F79 E3       02572 GRABNDO EX      (SP),HL         ;Save HL & get ret addr
0F7A 7E       02573         LD      A,(HL)          ;P/u & stuff error code
0F7B 23       02574         INC     HL              ;  start byte
0F7C 32B50F   02575         LD      (ERRSTRT+1),A
0F7F 7E       02576         LD      A,(HL)          ;Set up data transfer
0F80 23       02577         INC     HL              ;  direction vector
0F81 66       02578         LD      H,(HL)
0F82 6F       02579         LD      L,A
0F83 22930F   02580         LD      (CALLIO),HL     ;Stuff CALL vector
0F86 E1       02581         POP     HL              ;Restore buffer addr
              02582 ;
              02583 ;       Main I/O handler routine
              02584 ;
0F87 C5       02585 RETRY   PUSH    BC              ;Save retry & FDC command
0F88 D5       02586         PUSH    DE              ;Save track/sector
0F89 E5       02587         PUSH    HL              ;Save buffer
0F8A CB61     02588         BIT     4,C             ;Test for track command
0F8C CCE80E   02589         CALL    Z,SEEKTRK       ;Seek if not track write
0F8F CD820E   02590         CALL    TSTBSY          ;Wait till not busy
0F92 CD0000   02591         CALL    0               ;Call I/O routine
0F93          02592 CALLIO  EQU     $-2             ;Data xfer direction
0F95 00       02593 DISKEI  NOP                     ;Will be changed to a EI after
              02594                                 ;  BOOT has read in SYS0
0F96 DBF0     02595         IN      A,(FDCSTAT)     ;Get status
0F98 E67C     02596         AND     7CH             ;Strip all but 2-6
0F9A E1       02597         POP     HL
0F9B D1       02598         POP     DE              ;Rcvr track & sector
0F9C C1       02599         POP     BC              ;Rcvr retry count & cmd
0F9D C8       02600         RET     Z               ;Ret if no error
0F9E CB57     02601         BIT     2,A             ;Lost data?
0FA0 20E5     02602         JR      NZ,RETRY        ;Don't count this retry
0FA2 F5       02603         PUSH    AF
0FA3 E618     02604         AND     18H             ;Record not found or CRC
0FA5 280B     02605         JR      Z,DISKDUN       ;No retries if otherwise
0FA7 CB67     02606         BIT     4,A             ;Record not found?
0FA9 C5       02607         PUSH    BC              ;If so, switch
0FAA C4450E   02608         CALL    NZ,SWDEN        ;  density or restore
0FAD C1       02609         POP     BC
0FAE F1       02610         POP     AF
0FAF 10D6     02611         DJNZ    RETRY           ;Count down retry
0FB1 06       02612         DB      6               ;Ignore next with "LD B,nn"
0FB2 F1       02613 DISKDUN POP     AF              ;Adjust ret code
0FB3 47       02614         LD      B,A
0FB4 3E00     02615 ERRSTRT LD      A,0             ;Start with R=1, W=9
0FB6 CB08     02616 ERRTRAN RRC     B
0FB8 D8       02617         RET     C
0FB9 3C       02618         INC     A
0FBA 18FA     02619         JR      ERRTRAN
              02620 ;
              02621 ;       Write routine
              02622 ;
0FBC CD2B0F   02623 WROUT   CALL    RWINIT          ;Set up initialization
0FBF 1E76     02624         LD      E,76H           ;Status mask
0FC1 DBF0     02625 WRO1    IN      A,(FDCSTAT)     ;P/u status
0FC3 A3       02626         AND     E               ;Fall out on DRQ or error
0FC4 28FB     02627         JR      Z,WRO1          ;  else loop
0FC6 EDA3     02628         OUTI                    ;Xfer byte to FDC
0FC8 F3       02629         DI                      ;Now kill the interrupts
0FC9 DBF0     02630         IN      A,(FDCSTAT)     ;Check for errors
0FCB 1F       02631         RRA                     ;Did BUSY drop?
0FCC D0       02632         RET     NC              ;Quit now if so
0FCD 3EC0     02633         LD      A,0C0H          ;Enable INTRQ and timeout
0FCF D3E4     02634         OUT     (WRNMIPORT),A
0FD1 0650     02635         LD      B,50H           ;Time delay for WRSEC
0FD3 10FE     02636         DJNZ    $
0FD5 46       02637         LD      B,(HL)          ;Get next byte early
0FD6 23       02638         INC     HL
0FD7 7A       02639 WRO3    LD      A,D             ;Enable wait states
0FD8 D3F4     02640         OUT     (DSELCT),A
0FDA DBF0     02641         IN      A,(FDCSTAT)     ;Check if timed out
0FDC A3       02642         AND     E               ;Loop back if it timed
0FDD 28F8     02643         JR      Z,WRO3          ;  out (must be WRTRK)
0FDF ED41     02644         OUT     (C),B           ;Pass 2nd byte
0FE1 7A       02645         LD      A,D             ;Get sel code + WSGEN bit
0FE2 D3F4     02646 WRO2    OUT     (DSELCT),A      ;Pass until FDC times out
0FE4 EDA3     02647         OUTI                    ;  & generates NMI
0FE6 18FA     02648         JR      WRO2
              02649         IFEQ    $&0FFH,0FFH
              02650         ERR     'Warning... BUCKET position error
              02651         ENDIF
0FE8 53       02652 BUCKET  DB      'S'
              02653 ;
0FE9 AF       02654 @RSTNMI XOR     A               ;NMI vectors here
0FEA D3E4     02655         OUT     (WRNMIPORT),A   ;Disable INTRQ & timeout
0FEC 016400   02656         LD      BC,100          ;Need to wait a moment
0FEF CD8203   02657         CALL    PAUSE@          ;Call pause
0FF2 E1       02658         POP     HL              ;Discard return
0FF3 C9       02659         RET
0FF3          02660 FDCEND  EQU     $-1
0FF4          02661 DVREND$ EQU     $               ;Start of low I/O area,  to 12FFH
              02662         IFGT    $,1200H+START$
              02663         ERR     'Drivers overflow available RAM
              02664         ENDIF
1300          02665         ORG     1300H+START$
1300          02666 @BYTEIO EQU     $
0000          02667         END
0000 is the transfer address
00000 Total errors


[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_2011 at nemesis.lonestar.org]

Valid HTML 4.01!