diff --git a/doug/Makefile b/doug/Makefile deleted file mode 100755 index 3b1125ee..00000000 --- a/doug/Makefile +++ /dev/null @@ -1,692 +0,0 @@ -######################################################## -# Makefile for Doug's Unified BIOS 8/07/2011 # -# The BIOS and associated utilities are generated # -# using the Small Device C Compiler (SDCC) & tools # -# With multiplatform enhancements by John Coffman # -# # -# sdcc.l00 added because stupid Windoze 'echo' appends # -# a confusing SPACE to the end of every line. # -######################################################## - -##################################################### -# SPREFIX tells where the SDCC package in installed # -# The SDCC package is used to assemble Z80 portions # -# of the software such as the ROM and perhaps some # -# .COM files such as FDISK. # -##################################################### - -################################################################# -# TPREFIX tells where the host development tools are installed. # -# The host tools are used to manipulate the Z80 objects after # -# the basic assemblies and compilations have been completed. # -################################################################# - -################################################################### -# SDCC is not available on the DOS host, so something else may be # -# used at the descretion of the builder. (TASM for instance). # -################################################################### - -################################################################### -# The COPY, DEL and RENAME macros are used to customize the build # -# rules for the host enviroonment. # -################################################################### - -#------------------------------------------- -# Choose one only, then Make will work for -# your platform. - -CFG = $(shell uname) -# Mac OS X returns 'Darwin' -# Linux returns 'Linux' - -#CFG = dos -#CFG = linux -#CFG = macosx -#CFG = windows - -#------------------------------------------- -ifeq ($(CFG),Darwin) -DELIM = / -SPREFIX = /Developer/sdcc -SDAS = $(SPREFIX)/bin/sdasz80 -SDASFLG = -plosff -Iinc -SDCC = $(SPREFIX)/bin/sdcc -SDCCFLG = -c -mz80 -D__SDCC__=1 -I inc -SDCCLIB = $(SPREFIX)/share/sdcc/lib/z80 -SDLD = $(SPREFIX)/bin/sdldz80 -SDLDFLG = -TPREFIX = -TCC = gcc -TCCFLG = -I inc -COPY = cp -DEL = rm -DELFLG = -f -# use native ECHO o Mac OS X -ECHO = echo -REN = mv -EXE = -endif -#------------------------------------------- -ifeq ($(CFG),windows) -DELIM = \ -SDRIVE = C: -SPREFIX = $(SDRIVE)\Program Files (x86)\sdcc -SDAS = $(SPREFIX)\bin\sdasz80 -SDASFLG = -plosff -SDCC = $(SPREFIX)\bin\sdcc -SDCCFLG = -c -mz80 -D__SDCC__=1 -I inc -SDCCLIB = $(SPREFIX)\lib\z80 -SDLD = $(SPREFIX)\bin\sdldz80 -SDLDFLG = -TPREFIX = -TCC = gcc -TCCOPT = -I inc -COPY = copy -DEL = erase -DELFLG = -REN = rename - -# This is special handling for John Coffman to get around funky windows -# behavior where echo adds spurious space o end f line -# ECHO = { lecho | lechocr | lecholf | lechocrlf | lecholfcr } - -#ECHO = $(BIN)$(DELIM)lechocr -#ECHO = $(BIN)$(DELIM)lecho - -EXE = .exe -endif - -#------------------------------------------- -ifeq ($(CFG),Linux) -DELIM = / -SPREFIX = /home/$(USER) -SDAS = $(SPREFIX)/bin/sdasz80 -SDASFLG = -plosff -SDCC = $(SPREFIX)/bin/sdcc -SDCCFLG = -c -mz80 -D__SDCC__=1 -I inc -SDCCLIB = /usr/local/share/sdcc/lib/z80 -SDLD = $(SPREFIX)/bin/sdldz80 -SDLDFLG = -TPREFIX = -TCC = gcc -TCCFLG = -I inc -COPY = cp -DEL = rm -DELFLG = -f -REN = mv -# Use native 'echo' on Linux -ECHO = echo -EXE = -endif -#------------------------------------------- -ifeq ($(CFG),dos) -DELIM = \ -SPREFIX = -SDAS = -SDASFLG = -SDCC = -SDCCFLG = -SDCCLIB = -SDLD = -SDLDFLG = -TPREFIX = -TCC = wcl -TCCOPT = -COPY = copy -DEL = erase -DELFLG = -REN = rename -EXE = .exe -endif -############################################################ - -# Misc other macros - -BIN = bin$(DELIM) -COM = com$(DELIM) -INC = inc$(DELIM) -LIB = lib$(DELIM) -LST = lst$(DELIM) -MAP = map$(DELIM) -OBJ = obj$(DELIM) -REF = ref$(DELIM) -ROM = rom$(DELIM) -SRC = src$(DELIM) -TMP = tmp$(DELIM) - -# CP/M-80 v2.2 Command files written in SDCC -COMFILES = $(COM)copyfile.com $(COM)fdisk.com - -# Components used by CP/M-80 v2.2 Command files -COMRELS = $(OBJ)cpm0.rel $(OBJ)cpmbdos.rel $(OBJ)cprintf.rel - -# Components of ROM image containing CP/M for SBC V2 -CPMRELS = $(OBJ)crt0.rel $(OBJ)dbgmon.rel $(OBJ)bdosb01.rel \ - $(OBJ)ccpb03.rel $(OBJ)cbios.rel - -# Components of ROM image used in test protocols -ROMRELS = $(OBJ)crt0jplp.rel $(OBJ)crt0scrm.rel - -# Components that control hardware in SBC V2 -SBCV2HW = - -# Components that control hardware in the SCSI2IDE -SCSI2IDEHW = $(OBJ)z53c80.rel - -FDISK = $(BIN)fdisk$(EXE) -DWGH2B = $(BIN)dwgh2b$(EXE) -INCFILES = $(INC)cpmbdos.h $(INC)cprintf.h $(INC)portab.h -JRCH2B = $(BIN)jrch2b$(EXE) -LOAD = $(BIN)load$(EXE) -MK = Makefile -#QUIET = @ - -# ROM images for SBC V2 and N8 -ROMFILES = $(ROM)scsiscrm.rom $(ROM)scsijplp.rom $(ROM)scsi2ide.rom $(ROM)baseline.rom $(ROM)n8.rom -SCSI2IDE = $(ROM)scsi2ide.rom - -SYSGEN = $(BIN)sysgen$(EXE) -VERIFY = $(BIN)verify$(EXE) - -# C programs compiled on host system used in build -TOOLS = $(FDISK) $(DWGH2B) $(LOAD) $(JRCH2B) $(SYSGEN) - -# Versions of 'echo' compiled on host system -ETOOLS = $(BIN)lechocr $(BIN)lecholf $(BIN)lechocrlf $(BIN)lecholfcr - -# dribdos.rel is not part of the production set yet -##TEST = dribdos.rel - -############################################################ - -#all: $(ETOOLS) $(TOOLS) $(BINFILES) $(COMFILES) $(CPMFILES) $(ROMFILES) - -#all: $(TEST) $(ROMFILES) $(COMFILES) - -roms: $(ROMFILES) -scsi2ide: $(SCSI2IDE) - -############################################################ - -# A test assembly of DRI source code for BDOS (from SIMH) -dribdos.rel: $(SRC)dribdos.s - $(QUIET)$(SDAS) $(SDASFLG) dribdos.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)dribdos.lst $(LST) - -############################################################ -############################################################ - -# Build SCSIJPLP ROM image - -$(ROM)scsijplp.rom: $(OBJ)scsijplp.bin $(MK) - $(QUIET)$(COPY) $(OBJ)scsijplp.bin $(ROM)scsijplp.rom - $(QUIET)$(DEL) $(DELFLG) scsijplp.* - -$(OBJ)scsijplp.bin: $(OBJ)scsijplp.hex $(DWGH2B) $(MK) - $(QUIET)$(DWGH2B) $(OBJ)scsijplp - -$(OBJ)scsijplp.hex: $(OBJ)scsijplp.ihx $(MK) - $(QUIET)$(COPY) $(OBJ)scsijplp.ihx $(OBJ)scsijplp.hex - -$(OBJ)scsijplp.ihx: $(OBJ)crt0jplp.rel $(TMP)scsijplp.arf $(MK) - $(QUIET)$(COPY) $(TMP)scsijplp.arf $(TMP)scsijplp.lk - $(QUIET)$(COPY) $(TMP)scsijplp.arf $(TMP)scsijplp.lnk - $(QUIET)$(SDLD) $(SDLDFLG) -nf $(TMP)scsijplp.lnk - $(QUIET)$(COPY) $(COPYFLG) scsijplp.ihx $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) scsijplp.map $(MAP) - -######################################################### -# Dynamically generate linker control file for scsi2ide # -# (now uses the macro controlled ECHO feature # -######################################################### -$(TMP)scsijplp.arf: $(MK) - $(ECHO) -mjx > $(TMP)scsijplp.arf - $(ECHO) -i scsijplp.ihx >> $(TMP)scsijplp.arf - $(ECHO) -k $(SDCCLIB) >> $(TMP)scsijplp.arf - $(ECHO) -l z80 >> $(TMP)scsijplp.arf - $(ECHO) $(OBJ)crt0jplp.rel >> $(TMP)scsijplp.arf - $(ECHO) -e >> $(TMP)scsijplp.arf - -############################################################ -############################################################ - -# Build SCSISCRM ROM image - -$(ROM)scsiscrm.rom: $(OBJ)scsiscrm.bin $(MK) - $(QUIET)$(COPY) $(OBJ)scsiscrm.bin $(ROM)scsiscrm.rom - $(QUIET)$(DEL) $(DELFLG) scsiscrm.* - -$(OBJ)scsiscrm.bin: $(OBJ)scsiscrm.hex $(DWGH2B) $(MK) - $(QUIET)$(DWGH2B) $(OBJ)scsiscrm - -$(OBJ)scsiscrm.hex: $(OBJ)scsiscrm.ihx $(MK) - $(QUIET)$(COPY) $(OBJ)scsiscrm.ihx $(OBJ)scsiscrm.hex - -$(OBJ)scsiscrm.ihx: $(OBJ)crt0scrm.rel $(TMP)scsiscrm.arf $(MK) - $(QUIET)$(COPY) $(TMP)scsiscrm.arf $(TMP)scsiscrm.lk - $(QUIET)$(COPY) $(TMP)scsiscrm.arf $(TMP)scsiscrm.lnk - $(QUIET)$(SDLD) $(SDLDFLG) -nf $(TMP)scsiscrm.lnk - $(QUIET)$(COPY) $(COPYFLG) scsiscrm.ihx $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) scsiscrm.map $(MAP) - -######################################################### -# Dynamically generate linker control file for scsiscrm # -# (now uses the macro controlled ECHO feature # -######################################################### -$(TMP)scsiscrm.arf: $(MK) - $(ECHO) -mjx > $(TMP)scsiscrm.arf - $(ECHO) -i scsiscrm.ihx >> $(TMP)scsiscrm.arf - $(ECHO) -k $(SDCCLIB) >> $(TMP)scsiscrm.arf - $(ECHO) -l z80 >> $(TMP)scsiscrm.arf - $(ECHO) $(OBJ)crt0scrm.rel >> $(TMP)scsiscrm.arf - $(ECHO) -e >> $(TMP)scsiscrm.arf - -############################################################ -############################################################ - -# Build SCSI2IDE ROM image - -$(ROM)scsi2ide.rom: $(OBJ)scsi2ide.bin $(MK) - $(QUIET)$(COPY) $(OBJ)scsi2ide.bin $(ROM)scsi2ide.rom - $(QUIET)$(DEL) $(DELFLG) scsi2ide.* - -$(OBJ)scsi2ide.bin: $(OBJ)scsi2ide.hex $(DWGH2B) $(MK) - $(QUIET)$(DWGH2B) $(OBJ)scsi2ide - -$(OBJ)scsi2ide.hex: $(OBJ)scsi2ide.ihx $(MK) - $(QUIET)$(COPY) $(OBJ)scsi2ide.ihx $(OBJ)scsi2ide.hex - -$(OBJ)scsi2ide.ihx: $(CPMRELS) $(SCSI2IDEHW) $(OBJ)scsi2ide.rel $(TMP)scsi2ide.arf $(MK) - $(QUIET)$(COPY) $(TMP)scsi2ide.arf $(TMP)scsi2ide.lk - $(QUIET)$(COPY) $(TMP)scsi2ide.arf $(TMP)scsi2ide.lnk - $(QUIET)$(SDLD) $(SDLDFLG) -nf $(TMP)scsi2ide.lnk - $(QUIET)$(COPY) $(COPYFLG) scsi2ide.ihx $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) scsi2ide.map $(MAP) - -######################################################### -# Dynamically generate linker control file for scsi2ide # -# (now uses the macro controlled ECHO feature # -######################################################### -$(TMP)scsi2ide.arf: $(MK) - $(ECHO) -mjx > $(TMP)scsi2ide.arf - $(ECHO) -i scsi2ide.ihx >> $(TMP)scsi2ide.arf - $(ECHO) -k $(SDCCLIB) >> $(TMP)scsi2ide.arf - $(ECHO) -l z80 >> $(TMP)scsi2ide.arf -# $(ECHO) -b _CCPB03 = 0xD000 >> $(TMP)scsi2ide.arf -# $(ECHO) -b _BDOSB01 = 0xD800 >> $(TMP)scsi2ide.arf -# $(ECHO) -b _CBIOS = 0xE600 >> $(TMP)scsi2ide.arf -# $(ECHO) -b _DBGMON = 0x8000 >> $(TMP)scsi2ide.arf - $(ECHO) $(OBJ)crt0.rel >> $(TMP)scsi2ide.arf - $(ECHO) $(OBJ)scsi2ide.rel >> $(TMP)scsi2ide.arf -# $(ECHO) $(OBJ)dbgmon.rel >> $(TMP)scsi2ide.arf -# $(ECHO) $(OBJ)ccpb03.rel >> $(TMP)scsi2ide.arf -# $(ECHO) $(OBJ)bdosb01.rel >> $(TMP)scsi2ide.arf -# $(ECHO) $(OBJ)cbios.rel >> $(TMP)scsi2ide.arf - $(ECHO) -e >> $(TMP)scsi2ide.arf - -######################################################## -# Compile C portion of the scsi2ide EEPROM Image -$(OBJ)scsi2ide.rel: $(SRC)scsi2ide.c $(MK) - $(QUIET)$(SDCC) $(SDCCFLG) -c $(SRC)scsi2ide.c - $(QUIET)$(COPY) $(COPYFLG) scsi2ide.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) scsi2ide.lst $(LST) - - -############################################################ -############################################################ - -# Build SBC V2 ROM image - -$(ROM)baseline.rom: $(OBJ)baseline.bin $(MK) - $(QUIET)$(COPY) $(OBJ)baseline.bin $(ROM)baseline.rom - $(QUIET)$(DEL) $(DELFLG) baseline.* - -$(OBJ)baseline.bin: $(OBJ)baseline.hex $(DWGH2B) $(MK) - $(QUIET)$(DWGH2B) $(OBJ)baseline - -$(OBJ)baseline.hex: $(OBJ)baseline.ihx $(MK) - $(QUIET)$(COPY) $(OBJ)baseline.ihx $(OBJ)baseline.hex - -$(OBJ)baseline.ihx: $(CPMRELS) $(SBCV2HW) $(OBJ)baseline.rel $(TMP)baseline.arf $(MK) - $(QUIET)$(COPY) $(TMP)baseline.arf $(TMP)baseline.lk - $(QUIET)$(COPY) $(TMP)baseline.arf $(TMP)baseline.lnk - $(QUIET)$(SDLD) $(SDLDFLG) -nf $(TMP)baseline.lnk - $(QUIET)$(COPY) $(COPYFLG) baseline.ihx $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) baseline.map $(MAP) - -######################################################### -# Dynamically generate linker control file for baseline # -# (now uses the macro controlled ECHO feature # -######################################################### -$(TMP)baseline.arf: $(MK) - $(ECHO) -mjx > $(TMP)baseline.arf - $(ECHO) -i baseline.ihx >> $(TMP)baseline.arf - $(ECHO) -k $(SDCCLIB) >> $(TMP)baseline.arf - $(ECHO) -l z80 >> $(TMP)baseline.arf - $(ECHO) -b _CCPB03 = 0xD000 >> $(TMP)baseline.arf - $(ECHO) -b _BDOSB01 = 0xD800 >> $(TMP)baseline.arf - $(ECHO) -b _CBIOS = 0xE600 >> $(TMP)baseline.arf - $(ECHO) -b _DBGMON = 0x8000 >> $(TMP)baseline.arf - $(ECHO) $(OBJ)crt0.rel >> $(TMP)baseline.arf - $(ECHO) $(OBJ)baseline.rel >> $(TMP)baseline.arf - $(ECHO) $(OBJ)dbgmon.rel >> $(TMP)baseline.arf - $(ECHO) $(OBJ)ccpb03.rel >> $(TMP)baseline.arf - $(ECHO) $(OBJ)bdosb01.rel >> $(TMP)baseline.arf - $(ECHO) $(OBJ)cbios.rel >> $(TMP)baseline.arf - $(ECHO) -e >> $(TMP)baseline.arf - -######################################################## -# Compile C portion of the Baseline PROM Image -$(OBJ)baseline.rel: $(SRC)baseline.c $(MK) - $(QUIET)$(SDCC) $(SDCCFLG) -c $(SRC)baseline.c - $(QUIET)$(COPY) $(COPYFLG) baseline.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) baseline.lst $(LST) - -############################################################ - -# Build N8 ROM image - -# -# Save the resulting merged image in the Rom folder -# -$(ROM)n8.rom: $(OBJ)n8-romim.bin $(MK) - $(QUIET)$(COPY) $(OBJ)n8-romim.bin $(ROM)n8.rom - $(QUIET)$(DEL) $(DELFLG) n8.* - -# -# Convert the Intel hex file into a binary, similar -# to the results of the "copy /B ..." -# -$(OBJ)n8-romim.bin: $(OBJ)sysimage.hex $(REF)n8-romim.ref $(SYSGEN) $(HEX2BIN) $(MK) - $(QUIET)$(DWGH2B) $(OBJ)sysimage - $(QUIET)$(COPY) $(REF)n8-romim.ref $(OBJ)n8-romim.bin - $(QUIET)$(SYSGEN) -i $(OBJ)sysimage.bin $(OBJ)n8-romim.bin - -# -# Take the output of the linker and rename to the more -# recognizable .hex form and the expected name "sysimage.hex" -# -$(OBJ)sysimage.hex: $(OBJ)n8.ihx $(MK) - $(QUIET)$(COPY) $(OBJ)n8.ihx $(OBJ)sysimage.hex - -# -# Combine the independently assembled components into one piece -# and output Intel hex file (ihx) -# -$(OBJ)n8.ihx: $(OBJ)loadern8.rel $(OBJ)dbgmon.rel $(OBJ)ccpb03.rel $(OBJ)bdosb01.rel $(OBJ)cbiosn8.rel $(TMP)n8.arf $(MK) - $(QUIET)$(COPY) $(TMP)n8.arf $(TMP)n8.lk - $(QUIET)$(COPY) $(TMP)n8.arf $(TMP)n8.lnk - $(QUIET)$(SDLD) $(SDLDFLG) -nf $(TMP)n8.lnk - $(QUIET)$(COPY) $(COPYFLG) n8.ihx $(OBJ)n8.ihx - $(QUIET)$(COPY) $(COPYFLG) n8.map $(MAP) - -$(OBJ)cbiosn8.rel: $(SRC)cbiosn8.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)cbiosn8.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)cbiosn8.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)cbiosn8.lst $(LST) - -$(OBJ)loadern8.rel: $(SRC)loadern8.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)loadern8.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)loadern8.rel $(OBJ) - $(QUIET)$(COPY $(COPYFLG) $(SRC)loadern8.lst $(LST) - -######################################################## -# Dynamically generate the linker control file for N8 # -# Now uses the macro controlled ECHO feature # -######################################################## -$(TMP)n8.arf: Makefile - $(ECHO) -mjx > $(TMP)n8.arf - $(ECHO) -i n8.ihx >> $(TMP)n8.arf - $(ECHO) -k /usr/local/share/sdcc/lib/z80 >> $(TMP)n8.arf - $(ECHO) -l z80 >> $(TMP)n8.arf - $(ECHO) -b _CCPB03 = 0x0900 >> $(TMP)n8.arf - $(ECHO) -b _BDOSB01 = 0x1100 >> $(TMP)n8.arf - $(ECHO) -b _CBIOS = 0x1f00 >> $(TMP)n8.arf - $(ECHO) $(OBJ)loadern8.rel >> $(TMP)n8.arf - $(ECHO) $(OBJ)dbgmon.rel >> $(TMP)n8.arf - $(ECHO) $(OBJ)ccpb03.rel >> $(TMP)n8.arf - $(ECHO) $(OBJ)bdosb01.rel >> $(TMP)n8.arf - $(ECHO) $(OBJ)cbiosn8.rel >> $(TMP)n8.arf - $(ECHO) -e >> $(TMP)n8.arf - -############################################################ - -# Hardware specific assemblies (most likely used by BIOS's) - -# -# Assemble hardware control code for the Zilog Z53C8003V5C -# -$(OBJ)z53c80.rel: $(SRC)z53c80.c $(MK) - $(QUIET)$(SDCC) $(SDCCFLG) $(SRC)z53c80.c - $(QUIET)$(COPY) $(COPYFLG) z53c80.rel $(OBJ) - $(QUIET)$(DEL) $(DELFLG) z53c80.* - -# -# Compile ersatz printf routine for use in CP/M-80 command files -# -$(OBJ)cprintf.rel: $(SRC)cprintf.c $(MK) - $(QUIET)$(SDCC) $(SDCCFLG) $(SRC)cprintf.c - $(QUIET)$(COPY) $(COPYFLG) cprintf.rel obj - $(QUIET)$(DEL) $(DELFLG) cprintf.* - -############################################################ - -# Build CP/M 2.2 command files (copyfile.com, fdisk.com) - -#----------------------------------------------------------- - -$(COM)copyfile.com: $(OBJ)copyfile.com $(MK) - $(QUIET)$(COPY) $(OBJ)copyfile.com $(COM)copyfile.com - $(QUIET)$(DEL) $(DELFLG) copyfile.* - -$(OBJ)copyfile.com: $(OBJ)copyfile.hex $(LOAD) $(BINFILES) $(MK) - $(QUIET)$(LOAD) $(OBJ)copyfile - -$(OBJ)copyfile.hex: $(OBJ)copyfile.ihx $(MK) - $(QUIET)$(COPY) $(OBJ)copyfile.ihx $(OBJ)copyfile.hex - -$(OBJ)copyfile.ihx: $(OBJ)copyfile.rel $(COMRELS) $(TMP)copyfile.arf $(MK) - $(QUIET)$(COPY) $(TMP)copyfile.arf $(TMP)copyfile.lnk - - $(QUIET)$(SDLD) $(LOPTS) -nf $(TMP)copyfile.lnk - $(QUIET)$(COPY) $(COPYFLG) copyfile.ihx obj - $(QUIET)$(COPY) $(COPYFLG) copyfile.map map - -############################################################## -# Dynamicaly create linker command file for copyfile utility # -# Now uses the macro controlled ECHO feature # -############################################################## -$(TMP)copyfile.arf: Makefile - $(ECHO) -mjx > $(TMP)copyfile.arf - $(ECHO) -i copyfile.ihx >> $(TMP)copyfile.arf - $(ECHO) -k $(SDCCLIB) >> $(TMP)copyfile.arf - $(ECHO) -l z80 >> $(TMP)copyfile.arf - $(ECHO) $(OBJ)cpm0.rel >> $(TMP)copyfile.arf - $(ECHO) $(OBJ)copyfile.rel >> $(TMP)copyfile.arf - $(ECHO) $(OBJ)cpmbdos.rel >> $(TMP)copyfile.arf - $(ECHO) $(OBJ)cprintf.rel >> $(TMP)copyfile.arf - $(ECHO) -e >> $(TMP)copyfile.arf - -$(OBJ)copyfile.rel: $(SRC)copyfile.c $(MK) - $(QUIET)$(SDCC) $(SDCCFLG) $(SRC)copyfile.c - $(QUIET)$(COPY) copyfile.rel obj - $(QUIET)$(DEL) $(DELFLG) copyfile.rel - ls obj - -#----------------------------------------------------------- - -# -# Use locally compiled 'load' command to covert Intel -# hex formal file to a binary CP/M-80 command file. -# -$(COM)fdisk.com: $(OBJ)fdisk.hex $(TOOLS) $(MK) - $(QUIET)$(BIN)load $(OBJ)fdisk - $(QUIET)$(COPY) $(COPYFLG) $(OBJ)fdisk.com com - $(QUIET)$(DEL) $(DELFLG) fdisk.* - -# -# rename 'ihx' output of linker to 'hex' - -$(OBJ)fdisk.hex: $(OBJ)fdisk.ihx $(MK) - $(QUIET)$(COPY) $(OBJ)fdisk.ihx $(OBJ)fdisk.hex - -$(OBJ)fdisk.ihx: $(OBJ)fdisk.rel $(TMP)fdisk.arf $(MK) - $(QUIET)$(COPY) $(TMP)fdisk.arf $(TMP)fdisk.lnk - $(QUIET)$(COPY) $(TMP)fdisk.arf $(TMP)fdisk.lk - $(QUIET)$(SDLD) $(SDLDFLG) -nf $(TMP)fdisk.lnk - $(QUIET)$(COPY) $(COPYFLG) fdisk.ihx $(OBJ)fdisk.ihx - $(QUIET)$(COPY) $(COPYFLG) fdisk.map map - -$(OBJ)fdisk.rel: $(SRC)fdisk.c $(INCFILES) $(MK) - $(QUIET)$(SDCC) -I inc $(SDCCFLG) $(SRC)fdisk.c - $(QUIET)$(COPY) $(COPYFLG) fdisk.rel $(OBJ) - -############################################################################ -# Dynamically created linker command file for fdisk utility (CP/M version) # -# Now uses macro controlled ECHO feature # -############################################################################ -$(TMP)fdisk.arf: $(MK) - $(ECHO) -mjx > $(TMP)fdisk.arf - $(ECHO) -i fdisk.ihx >> $(TMP)fdisk.arf - $(ECHO) -k $(SDCCLIB) >> $(TMP)fdisk.arf - $(ECHO) -l z80 >> $(TMP)fdisk.arf - $(ECHO) $(OBJ)cpm0.rel >> $(TMP)fdisk.arf - $(ECHO) $(OBJ)fdisk.rel >> $(TMP)fdisk.arf - $(ECHO) $(OBJ)cpmbdos.rel >> $(TMP)fdisk.arf - $(ECHO) $(OBJ)cprintf.rel >> $(TMP)fdisk.arf - $(ECHO) -e >> $(TMP)fdisk.arf - - -#----------------------------------------------------------- - -# Also build host version of fdisk for testing purposes - -$(BIN)fdisk$(EXE): $(SRC)fdisk.c $(MK) - $(QUIET)$(TCC) $(TCCFLG) $(SRC)fdisk.c -o $(BIN)fdisk - -############################################################ - -# Build CP/M-80 Command File Structure Files - -$(OBJ)cpm0.rel: $(SRC)cpm0.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)cpm0.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)cpm0.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)cpm0.lst $(LST) - -$(OBJ)cpmbdos.rel: $(SRC)cpmbdos.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)cpmbdos.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)cpmbdos.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)cpmbdos.lst $(LST) - -############################################################ - -# Build ROM Image structure files - -$(OBJ)crt0.rel: $(SRC)crt0.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)crt0.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)crt0.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)crt0.lst $(LST) - -$(OBJ)crt0jplp.rel: $(SRC)crt0jplp.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)crt0jplp.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)crt0jplp.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)crt0jplp.lst $(LST) - -$(OBJ)crt0scrm.rel: $(SRC)crt0scrm.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)crt0scrm.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)crt0scrm.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)crt0scrm.lst $(LST) - -$(OBJ)bdosb01.rel: $(SRC)bdosb01.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)bdosb01.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)bdosb01.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)bdosb01.lst $(LST) - -$(OBJ)ccpb03.rel: $(SRC)ccpb03.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)ccpb03.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)ccpb03.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)ccpb03.lst $(LST) - -# -# Assemble hardware control code for SBC V2 -# -$(OBJ)cbios.rel: $(SRC)cbios.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)cbios.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)cbios.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)cbios.lst $(LST) - -# -# Assemble a monitor program for the SBC V2 -# -$(OBJ)dbgmon.rel: $(SRC)dbgmon.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)dbgmon.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)dbgmon.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)dbgmon.lst $(LST) - -########################################################### - -# Build host based tools ( dwgh2b, jrch2b, load, verify) - -$(DWGH2B): $(SRC)dwgh2b.c $(MK) - $(QUIET)$(TCC) $(TCCFLG) $(SRC)dwgh2b.c -o $(BIN)dwgh2b$(EXE) - -# -# Compile John Coffman's hex2bin program -# -$(JRCH2B): $(SRC)jrch2b.c $(MK) - $(QUIET)$(TCC) $(TCCFLG) $(SRC)jrch2b.c -o $(BIN)jrch2b$(EXE) - $(QUIET)$(COPY) $(COPYFLG) $(BIN)jrch2b $(BIN)jrcb2h - -# -# Compile Doug's "load" program -# -$(LOAD): $(SRC)load.c $(MK) - $(QUIET)$(TCC) $(TCCFLG) $(SRC)load.c -o $(BIN)load$(EXE) - -$(SYSGEN): $(SRC)sysgen.c $(MK) - $(QUIET)$(TCC) $(TCCFLG) $(SRC)sysgen.c -o $(BIN)sysgen$(EXE) - -# -# Compile Doug's verif program that compares binary file regions -# -$(VERIFY): $(SRC)verify.c Makefile $(MK) - $(QUIET)$(TCC) $(TCCFLG) $(SRC)verify.c -o $(BIN)verify - -$(BIN)lechocr: $(SRC)lechocr.c $(MK) -# $(QUIET)$(TCC) $(TCCFLG) $(SRC)lechocr.c -o $(BIN)lechocr - $(QUIET)$(TCC) $(TCCFLG) $(SRC)lechocr.c - $(QUIET)$(COPY) lechocr.exe $(BIN) - -$(BIN)lecholf: $(SRC)lecholf.c $(MK) -# $(QUIET)$(TCC) $(TCCFLG) $(SRC)lecholf.c -o $(BIN)lecholf - $(QUIET)$(TCC) $(TCCFLG) $(SRC)lecholf.c - $(COPY) lecholf.exe $(BIN) - -$(BIN)lechocrlf: $(SRC)lechocrlf.c $(MK) - $(QUIET)$(TCC) $(TCCFLG) $(SRC)lechocrlf.c -o $(BIN)lechocrlf - -$(BIN)lecholfcr: $(SRC)lecholfcr.c $(MK) -# $(QUIET)$(TCC) $(TCCFLG) $(SRC)lecholfcr.c -o $(BIN)lecholfcr - $(QUIET)$(TCC) $(TCCFLG) $(SRC)lecholfcr.c -o $(BIN)lecholfcr - -############################################################ - -# Builder specific utility rules - -dwginstall: - $(COPY) $(COMFILES) ~/Documents/devobox/cdrive - -############################################################ - -# -# Delete all dynamically generated files that don't need to be -# saved. -# -clean: - $(QUIET)$(DEL) $(DELFLG) *.hex *.ihx *.lst *.rel *.rst *.lnk *.lk - $(QUIET)$(DEL) $(DELFLG) *.sym *.map *.noi *.asm *.com *.ini *.bin - $(QUIET)$(DEL) $(DELFLG) obj/* bin/* com/* rom/* tmp/* map/* lst/* - -################## -# eof - Makefile # -################## diff --git a/doug/doc/agm1264f.pdf b/doug/doc/agm1264f.pdf deleted file mode 100755 index 60eec3d9..00000000 Binary files a/doug/doc/agm1264f.pdf and /dev/null differ diff --git a/doug/doc/bdoscalls.webarchive b/doug/doc/bdoscalls.webarchive deleted file mode 100755 index 30b4faad..00000000 Binary files a/doug/doc/bdoscalls.webarchive and /dev/null differ diff --git a/doug/doc/bios.webarchive b/doug/doc/bios.webarchive deleted file mode 100755 index ede74cc5..00000000 Binary files a/doug/doc/bios.webarchive and /dev/null differ diff --git a/doug/doc/fcb.webarchive b/doug/doc/fcb.webarchive deleted file mode 100755 index d8468620..00000000 Binary files a/doug/doc/fcb.webarchive and /dev/null differ diff --git a/doug/doc/jrch2b.doc b/doug/doc/jrch2b.doc deleted file mode 100755 index 6231b4db..00000000 --- a/doug/doc/jrch2b.doc +++ /dev/null @@ -1,92 +0,0 @@ -Usage: - hex2bin [ ]+ - bin2hex - - Options: - -o -- default is 'out.bin' or 'out.hex' - No suffix is added to the filename, so the full - file name must be specified. - - -p -- default is 0xFF, which is the erased - value for most ROM's. Pad bytes are not explicitly - written out when 'bin2hex' is used. This reduces - the size of sparse ROM images. - - -R -- may be any value. Normally this will be - specified as '128k' or 0x10000. The suffixes 'k' - and 'M' are recognized. The default value is 64k - for 'hex2bin' and 1M for 'bin2hex'. - - -v [] -- used primarily for debugging. A - verbosity level of 3 will print each line as it is - processed. - - Options are global, and may be specified anywhere on the command - line. Only 'flags', below, are position sensitive. Flags must - be specified immediately before the file name they are to affect. - They do not affect more that a single file. They reset to their - default values before the next input file, scanning left to - right, is processed. - - Flags: - Flag values apply only to the following file, and are reset - to the default values before the next file is processed. The - source and destination flags allow code to be relocated - within the ROM so that code may be loaded at a different - location than where it will ultimately be run. - - -d -- default is 0. - data will only be loaded between the limits of - the -d address and the -D address - minus 1. - - -D -- default is 16M. No data - will be loaded at or above this address. - - -s -- default is 0. Hex input - is only processed if it falls at addresses in the - .hex input file between the -s address and the - -S address minus 1. Likewise, Bin input - is only processed if it falls between similar limits - in the input ROM image. - - -S -- default is 16M. No input - data at or above this address will be processed. - - Numeric values on the command line may be specified in any C-like - syntax: 0x0000 is hexadecimal, 1234 is decimal, and 0177 is - octal. In addition the suffixes 'k' for kilo- and 'M' for mega- - cause the preceding values to be multiplied by 1024 or 1048576, - respectively. - - Examples: - hex2bin -p 0xFF -R32k cpm22.hex -o cpmtest.bin - hex2bin -o cpmtest.bin cpm22.hex -R 0x8000 -p255 - - The preceding two lines have identical effects in all - respects. - - hex2bin -R 1M -s 0xd000 -d 0x0800 -D0x2800 image.hex \ - pagezero.hex -oROMIMAGE.bin - - The above line loads the 'pagezero.hex' file at the exact - addresses specified in the file; however, the 'image.hex' file - is assembled at 0xD000, must run at 0xD000, but is loaded - between 0x800 <= addr < 0x2800. It is presumed that the - code will be relocated to the correct address before it is - executed. - - bin2hex -R128k romimage.bin -o image.hex - - Simple conversion from a BIN file to a HEX file. The ROM - data is limited to 128k. - - bin2hex -s 0x1000 -S 0x2000 -d 0x21000 romimage.bin \ - -o Relocated.hex - - Extract from a ROM image file all of the data between 0x1000 - and 0x1FFF, inclusive, and write to an Intel hex file for - re-loading two 64k segments higher in a future ROM. - - -(end) diff --git a/doug/doc/make.pdf b/doug/doc/make.pdf deleted file mode 100755 index 3e18161c..00000000 Binary files a/doug/doc/make.pdf and /dev/null differ diff --git a/doug/doc/sdcc-z80-mode.png b/doug/doc/sdcc-z80-mode.png deleted file mode 100644 index 064b32b1..00000000 Binary files a/doug/doc/sdcc-z80-mode.png and /dev/null differ diff --git a/doug/doc/watcom-tools.pdf b/doug/doc/watcom-tools.pdf deleted file mode 100644 index 6d3f38c9..00000000 Binary files a/doug/doc/watcom-tools.pdf and /dev/null differ diff --git a/doug/exp/common.mak b/doug/exp/common.mak deleted file mode 100755 index 7430e334..00000000 --- a/doug/exp/common.mak +++ /dev/null @@ -1,558 +0,0 @@ -# mak/makebody.mfi 8/8/2011 dwg - - -# Misc other macros - -BIN = bin$(DELIM) -COM = com$(DELIM) -INC = inc$(DELIM) -LIB = lib$(DELIM) -LST = lst$(DELIM) -MAP = map$(DELIM) -OBJ = obj$(DELIM) -REF = ref$(DELIM) -ROM = rom$(DELIM) -SRC = src$(DELIM) -TMP = tmp$(DELIM) - -# CP/M-80 v2.2 Command files written in SDCC -COMFILES = $(COM)copyfile.com $(COM)fdisk.com - -# Components used by CP/M-80 v2.2 Command files -COMRELS = $(OBJ)cpm0.rel $(OBJ)cpmbdos.rel $(OBJ)cprintf.rel - -# Components of ROM image containing CP/M for SBC V2 -CPMRELS = $(OBJ)crt0.rel $(OBJ)dbgmon.rel $(OBJ)bdosb01.rel \ - $(OBJ)ccpb03.rel $(OBJ)cbios.rel - -# Components of ROM image used in test protocols -ROMRELS = $(OBJ)crt0jplp.rel $(OBJ)crt0scrm.rel - -# Components that control hardware in SBC V2 -SBCV2HW = - -# Components that control hardware in the SCSI2IDE -SCSI2IDEHW = $(OBJ)z53c80.rel - -FDISK = $(BIN)fdisk$(EXE) -DWGH2B = $(BIN)dwgh2b$(EXE) -INCFILES = $(INC)cpmbdos.h $(INC)cprintf.h $(INC)portab.h -JRCH2B = $(BIN)jrch2b$(EXE) -LOAD = $(BIN)load$(EXE) -MK = Makefile -#QUIET = @ - -# ROM images for SBC V2 and N8 -ROMFILES = $(ROM)scsiscrm.rom $(ROM)scsijplp.rom $(ROM)scsi2ide.rom $(ROM)baseline.rom $(ROM)n8.rom -SCSI2IDE = $(ROM)scsi2ide.rom - -SYSGEN = $(BIN)sysgen$(EXE) -VERIFY = $(BIN)verify$(EXE) - -# C programs compiled on host system used in build -TOOLS = $(FDISK) $(DWGH2B) $(LOAD) $(JRCH2B) $(SYSGEN) - -# Versions of 'echo' compiled on host system -ETOOLS = $(BIN)lechocr $(BIN)lecholf $(BIN)lechocrlf $(BIN)lecholfcr - -# dribdos.rel is not part of the production set yet -##TEST = dribdos.rel - -############################################################ - -#all: $(ETOOLS) $(TOOLS) $(BINFILES) $(COMFILES) $(CPMFILES) $(ROMFILES) - -#all: $(TEST) $(ROMFILES) $(COMFILES) - -roms: $(ROMFILES) -scsi2ide: $(SCSI2IDE) - -############################################################ - -# A test assembly of DRI source code for BDOS (from SIMH) -dribdos.rel: $(SRC)dribdos.s - $(QUIET)$(SDAS) $(SDASFLG) dribdos.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)dribdos.lst $(LST) - -############################################################ -############################################################ - -# Build SCSIJPLP ROM image - -$(ROM)scsijplp.rom: $(OBJ)scsijplp.bin $(MK) - $(QUIET)$(COPY) $(OBJ)scsijplp.bin $(ROM)scsijplp.rom - $(QUIET)$(DEL) $(DELFLG) scsijplp.* - -$(OBJ)scsijplp.bin: $(OBJ)scsijplp.hex $(DWGH2B) $(MK) - $(QUIET)$(DWGH2B) $(OBJ)scsijplp - -$(OBJ)scsijplp.hex: $(OBJ)scsijplp.ihx $(MK) - $(QUIET)$(COPY) $(OBJ)scsijplp.ihx $(OBJ)scsijplp.hex - -$(OBJ)scsijplp.ihx: $(OBJ)crt0jplp.rel $(TMP)scsijplp.arf $(MK) - $(QUIET)$(COPY) $(TMP)scsijplp.arf $(TMP)scsijplp.lk - $(QUIET)$(COPY) $(TMP)scsijplp.arf $(TMP)scsijplp.lnk - $(QUIET)$(SDLD) $(SDLDFLG) -nf $(TMP)scsijplp.lnk - $(QUIET)$(COPY) $(COPYFLG) scsijplp.ihx $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) scsijplp.map $(MAP) - -######################################################### -# Dynamically generate linker control file for scsi2ide # -# (now uses the macro controlled ECHO feature # -######################################################### -$(TMP)scsijplp.arf: $(MK) - $(ECHO) -mjx > $(TMP)scsijplp.arf - $(ECHO) -i scsijplp.ihx >> $(TMP)scsijplp.arf - $(ECHO) -k $(SDCCLIB) >> $(TMP)scsijplp.arf - $(ECHO) -l z80 >> $(TMP)scsijplp.arf - $(ECHO) $(OBJ)crt0jplp.rel >> $(TMP)scsijplp.arf - $(ECHO) -e >> $(TMP)scsijplp.arf - -############################################################ -############################################################ - -# Build SCSISCRM ROM image - -$(ROM)scsiscrm.rom: $(OBJ)scsiscrm.bin $(MK) - $(QUIET)$(COPY) $(OBJ)scsiscrm.bin $(ROM)scsiscrm.rom - $(QUIET)$(DEL) $(DELFLG) scsiscrm.* - -$(OBJ)scsiscrm.bin: $(OBJ)scsiscrm.hex $(DWGH2B) $(MK) - $(QUIET)$(DWGH2B) $(OBJ)scsiscrm - -$(OBJ)scsiscrm.hex: $(OBJ)scsiscrm.ihx $(MK) - $(QUIET)$(COPY) $(OBJ)scsiscrm.ihx $(OBJ)scsiscrm.hex - -$(OBJ)scsiscrm.ihx: $(OBJ)crt0scrm.rel $(TMP)scsiscrm.arf $(MK) - $(QUIET)$(COPY) $(TMP)scsiscrm.arf $(TMP)scsiscrm.lk - $(QUIET)$(COPY) $(TMP)scsiscrm.arf $(TMP)scsiscrm.lnk - $(QUIET)$(SDLD) $(SDLDFLG) -nf $(TMP)scsiscrm.lnk - $(QUIET)$(COPY) $(COPYFLG) scsiscrm.ihx $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) scsiscrm.map $(MAP) - -######################################################### -# Dynamically generate linker control file for scsiscrm # -# (now uses the macro controlled ECHO feature # -######################################################### -$(TMP)scsiscrm.arf: $(MK) - $(ECHO) -mjx > $(TMP)scsiscrm.arf - $(ECHO) -i scsiscrm.ihx >> $(TMP)scsiscrm.arf - $(ECHO) -k $(SDCCLIB) >> $(TMP)scsiscrm.arf - $(ECHO) -l z80 >> $(TMP)scsiscrm.arf - $(ECHO) $(OBJ)crt0scrm.rel >> $(TMP)scsiscrm.arf - $(ECHO) -e >> $(TMP)scsiscrm.arf - -############################################################ -############################################################ - -# Build SCSI2IDE ROM image - -$(ROM)scsi2ide.rom: $(OBJ)scsi2ide.bin $(MK) - $(QUIET)$(COPY) $(OBJ)scsi2ide.bin $(ROM)scsi2ide.rom - $(QUIET)$(DEL) $(DELFLG) scsi2ide.* - -$(OBJ)scsi2ide.bin: $(OBJ)scsi2ide.hex $(DWGH2B) $(MK) - $(QUIET)$(DWGH2B) $(OBJ)scsi2ide - -$(OBJ)scsi2ide.hex: $(OBJ)scsi2ide.ihx $(MK) - $(QUIET)$(COPY) $(OBJ)scsi2ide.ihx $(OBJ)scsi2ide.hex - -$(OBJ)scsi2ide.ihx: $(CPMRELS) $(SCSI2IDEHW) $(OBJ)scsi2ide.rel $(TMP)scsi2ide.arf $(MK) - $(QUIET)$(COPY) $(TMP)scsi2ide.arf $(TMP)scsi2ide.lk - $(QUIET)$(COPY) $(TMP)scsi2ide.arf $(TMP)scsi2ide.lnk - $(QUIET)$(SDLD) $(SDLDFLG) -nf $(TMP)scsi2ide.lnk - $(QUIET)$(COPY) $(COPYFLG) scsi2ide.ihx $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) scsi2ide.map $(MAP) - -######################################################### -# Dynamically generate linker control file for scsi2ide # -# (now uses the macro controlled ECHO feature # -######################################################### -$(TMP)scsi2ide.arf: $(MK) - $(ECHO) -mjx > $(TMP)scsi2ide.arf - $(ECHO) -i scsi2ide.ihx >> $(TMP)scsi2ide.arf - $(ECHO) -k $(SDCCLIB) >> $(TMP)scsi2ide.arf - $(ECHO) -l z80 >> $(TMP)scsi2ide.arf -# $(ECHO) -b _CCPB03 = 0xD000 >> $(TMP)scsi2ide.arf -# $(ECHO) -b _BDOSB01 = 0xD800 >> $(TMP)scsi2ide.arf -# $(ECHO) -b _CBIOS = 0xE600 >> $(TMP)scsi2ide.arf -# $(ECHO) -b _DBGMON = 0x8000 >> $(TMP)scsi2ide.arf - $(ECHO) $(OBJ)crt0.rel >> $(TMP)scsi2ide.arf - $(ECHO) $(OBJ)scsi2ide.rel >> $(TMP)scsi2ide.arf -# $(ECHO) $(OBJ)dbgmon.rel >> $(TMP)scsi2ide.arf -# $(ECHO) $(OBJ)ccpb03.rel >> $(TMP)scsi2ide.arf -# $(ECHO) $(OBJ)bdosb01.rel >> $(TMP)scsi2ide.arf -# $(ECHO) $(OBJ)cbios.rel >> $(TMP)scsi2ide.arf - $(ECHO) -e >> $(TMP)scsi2ide.arf - -######################################################## -# Compile C portion of the scsi2ide EEPROM Image -$(OBJ)scsi2ide.rel: $(SRC)scsi2ide.c $(MK) - $(QUIET)$(SDCC) $(SDCCFLG) -c $(SRC)scsi2ide.c - $(QUIET)$(COPY) $(COPYFLG) scsi2ide.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) scsi2ide.lst $(LST) - - -############################################################ -############################################################ - -# Build SBC V2 ROM image - -$(ROM)baseline.rom: $(OBJ)baseline.bin $(MK) - $(QUIET)$(COPY) $(OBJ)baseline.bin $(ROM)baseline.rom - $(QUIET)$(DEL) $(DELFLG) baseline.* - -$(OBJ)baseline.bin: $(OBJ)baseline.hex $(DWGH2B) $(MK) - $(QUIET)$(DWGH2B) $(OBJ)baseline - -$(OBJ)baseline.hex: $(OBJ)baseline.ihx $(MK) - $(QUIET)$(COPY) $(OBJ)baseline.ihx $(OBJ)baseline.hex - -$(OBJ)baseline.ihx: $(CPMRELS) $(SBCV2HW) $(OBJ)baseline.rel $(TMP)baseline.arf $(MK) - $(QUIET)$(COPY) $(TMP)baseline.arf $(TMP)baseline.lk - $(QUIET)$(COPY) $(TMP)baseline.arf $(TMP)baseline.lnk - $(QUIET)$(SDLD) $(SDLDFLG) -nf $(TMP)baseline.lnk - $(QUIET)$(COPY) $(COPYFLG) baseline.ihx $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) baseline.map $(MAP) - -######################################################### -# Dynamically generate linker control file for baseline # -# (now uses the macro controlled ECHO feature # -######################################################### -$(TMP)baseline.arf: $(MK) - $(ECHO) -mjx > $(TMP)baseline.arf - $(ECHO) -i baseline.ihx >> $(TMP)baseline.arf - $(ECHO) -k $(SDCCLIB) >> $(TMP)baseline.arf - $(ECHO) -l z80 >> $(TMP)baseline.arf - $(ECHO) -b _CCPB03 = 0xD000 >> $(TMP)baseline.arf - $(ECHO) -b _BDOSB01 = 0xD800 >> $(TMP)baseline.arf - $(ECHO) -b _CBIOS = 0xE600 >> $(TMP)baseline.arf - $(ECHO) -b _DBGMON = 0x8000 >> $(TMP)baseline.arf - $(ECHO) $(OBJ)crt0.rel >> $(TMP)baseline.arf - $(ECHO) $(OBJ)baseline.rel >> $(TMP)baseline.arf - $(ECHO) $(OBJ)dbgmon.rel >> $(TMP)baseline.arf - $(ECHO) $(OBJ)ccpb03.rel >> $(TMP)baseline.arf - $(ECHO) $(OBJ)bdosb01.rel >> $(TMP)baseline.arf - $(ECHO) $(OBJ)cbios.rel >> $(TMP)baseline.arf - $(ECHO) -e >> $(TMP)baseline.arf - -######################################################## -# Compile C portion of the Baseline PROM Image -$(OBJ)baseline.rel: $(SRC)baseline.c $(MK) - $(QUIET)$(SDCC) $(SDCCFLG) -c $(SRC)baseline.c - $(QUIET)$(COPY) $(COPYFLG) baseline.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) baseline.lst $(LST) - -############################################################ - -# Build N8 ROM image - -# -# Save the resulting merged image in the Rom folder -# -$(ROM)n8.rom: $(OBJ)n8-romim.bin $(MK) - $(QUIET)$(COPY) $(OBJ)n8-romim.bin $(ROM)n8.rom - $(QUIET)$(DEL) $(DELFLG) n8.* - -# -# Convert the Intel hex file into a binary, similar -# to the results of the "copy /B ..." -# -$(OBJ)n8-romim.bin: $(OBJ)sysimage.hex $(REF)n8-romim.ref $(SYSGEN) $(HEX2BIN) $(MK) - $(QUIET)$(DWGH2B) $(OBJ)sysimage - $(QUIET)$(COPY) $(REF)n8-romim.ref $(OBJ)n8-romim.bin - $(QUIET)$(SYSGEN) -i $(OBJ)sysimage.bin $(OBJ)n8-romim.bin - -# -# Take the output of the linker and rename to the more -# recognizable .hex form and the expected name "sysimage.hex" -# -$(OBJ)sysimage.hex: $(OBJ)n8.ihx $(MK) - $(QUIET)$(COPY) $(OBJ)n8.ihx $(OBJ)sysimage.hex - -# -# Combine the independently assembled components into one piece -# and output Intel hex file (ihx) -# -$(OBJ)n8.ihx: $(OBJ)loadern8.rel $(OBJ)dbgmon.rel $(OBJ)ccpb03.rel $(OBJ)bdosb01.rel $(OBJ)cbiosn8.rel $(TMP)n8.arf $(MK) - $(QUIET)$(COPY) $(TMP)n8.arf $(TMP)n8.lk - $(QUIET)$(COPY) $(TMP)n8.arf $(TMP)n8.lnk - $(QUIET)$(SDLD) $(SDLDFLG) -nf $(TMP)n8.lnk - $(QUIET)$(COPY) $(COPYFLG) n8.ihx $(OBJ)n8.ihx - $(QUIET)$(COPY) $(COPYFLG) n8.map $(MAP) - -$(OBJ)cbiosn8.rel: $(SRC)cbiosn8.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)cbiosn8.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)cbiosn8.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)cbiosn8.lst $(LST) - -$(OBJ)loadern8.rel: $(SRC)loadern8.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)loadern8.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)loadern8.rel $(OBJ) - $(QUIET)$(COPY $(COPYFLG) $(SRC)loadern8.lst $(LST) - -######################################################## -# Dynamically generate the linker control file for N8 # -# Now uses the macro controlled ECHO feature # -######################################################## -$(TMP)n8.arf: Makefile - $(ECHO) -mjx > $(TMP)n8.arf - $(ECHO) -i n8.ihx >> $(TMP)n8.arf - $(ECHO) -k $(SDCCLIB) >> $(TMP)n8.arf - $(ECHO) -l z80 >> $(TMP)n8.arf - $(ECHO) -b _CCPB03 = 0x0900 >> $(TMP)n8.arf - $(ECHO) -b _BDOSB01 = 0x1100 >> $(TMP)n8.arf - $(ECHO) -b _CBIOS = 0x1f00 >> $(TMP)n8.arf - $(ECHO) $(OBJ)loadern8.rel >> $(TMP)n8.arf - $(ECHO) $(OBJ)dbgmon.rel >> $(TMP)n8.arf - $(ECHO) $(OBJ)ccpb03.rel >> $(TMP)n8.arf - $(ECHO) $(OBJ)bdosb01.rel >> $(TMP)n8.arf - $(ECHO) $(OBJ)cbiosn8.rel >> $(TMP)n8.arf - $(ECHO) -e >> $(TMP)n8.arf - -############################################################ - -# Hardware specific assemblies (most likely used by BIOS's) - -# -# Assemble hardware control code for the Zilog Z53C8003V5C -# -$(OBJ)z53c80.rel: $(SRC)z53c80.c $(MK) - $(QUIET)$(SDCC) $(SDCCFLG) $(SRC)z53c80.c - $(QUIET)$(COPY) $(COPYFLG) z53c80.rel $(OBJ) - $(QUIET)$(DEL) $(DELFLG) z53c80.* - -# -# Compile ersatz printf routine for use in CP/M-80 command files -# -$(OBJ)cprintf.rel: $(SRC)cprintf.c $(MK) - $(QUIET)$(SDCC) $(SDCCFLG) $(SRC)cprintf.c - $(QUIET)$(COPY) $(COPYFLG) cprintf.rel obj - $(QUIET)$(DEL) $(DELFLG) cprintf.* - -############################################################ - -# Build CP/M 2.2 command files (copyfile.com, fdisk.com) - -#----------------------------------------------------------- - -$(COM)copyfile.com: $(OBJ)copyfile.com $(MK) - $(QUIET)$(COPY) $(OBJ)copyfile.com $(COM)copyfile.com - $(QUIET)$(DEL) $(DELFLG) copyfile.* - -$(OBJ)copyfile.com: $(OBJ)copyfile.hex $(LOAD) $(BINFILES) $(MK) - $(QUIET)$(LOAD) $(OBJ)copyfile - -$(OBJ)copyfile.hex: $(OBJ)copyfile.ihx $(MK) - $(QUIET)$(COPY) $(OBJ)copyfile.ihx $(OBJ)copyfile.hex - -$(OBJ)copyfile.ihx: $(OBJ)copyfile.rel $(COMRELS) $(TMP)copyfile.arf $(MK) - $(QUIET)$(COPY) $(TMP)copyfile.arf $(TMP)copyfile.lnk - - $(QUIET)$(SDLD) $(LOPTS) -nf $(TMP)copyfile.lnk - $(QUIET)$(COPY) $(COPYFLG) copyfile.ihx obj - $(QUIET)$(COPY) $(COPYFLG) copyfile.map map - -############################################################## -# Dynamicaly create linker command file for copyfile utility # -# Now uses the macro controlled ECHO feature # -############################################################## -$(TMP)copyfile.arf: Makefile - $(ECHO) -mjx > $(TMP)copyfile.arf - $(ECHO) -i copyfile.ihx >> $(TMP)copyfile.arf - $(ECHO) -k $(SDCCLIB) >> $(TMP)copyfile.arf - $(ECHO) -l z80 >> $(TMP)copyfile.arf - $(ECHO) $(OBJ)cpm0.rel >> $(TMP)copyfile.arf - $(ECHO) $(OBJ)copyfile.rel >> $(TMP)copyfile.arf - $(ECHO) $(OBJ)cpmbdos.rel >> $(TMP)copyfile.arf - $(ECHO) $(OBJ)cprintf.rel >> $(TMP)copyfile.arf - $(ECHO) -e >> $(TMP)copyfile.arf - -$(OBJ)copyfile.rel: $(SRC)copyfile.c $(MK) - $(QUIET)$(SDCC) $(SDCCFLG) $(SRC)copyfile.c - $(QUIET)$(COPY) copyfile.rel obj - $(QUIET)$(DEL) $(DELFLG) copyfile.rel - ls obj - -#----------------------------------------------------------- - -# -# Use locally compiled 'load' command to covert Intel -# hex formal file to a binary CP/M-80 command file. -# -$(COM)fdisk.com: $(OBJ)fdisk.hex $(TOOLS) $(MK) - $(QUIET)$(BIN)load $(OBJ)fdisk - $(QUIET)$(COPY) $(COPYFLG) $(OBJ)fdisk.com com - $(QUIET)$(DEL) $(DELFLG) fdisk.* - -# -# rename 'ihx' output of linker to 'hex' - -$(OBJ)fdisk.hex: $(OBJ)fdisk.ihx $(MK) - $(QUIET)$(COPY) $(OBJ)fdisk.ihx $(OBJ)fdisk.hex - -$(OBJ)fdisk.ihx: $(OBJ)fdisk.rel $(TMP)fdisk.arf $(MK) - $(QUIET)$(COPY) $(TMP)fdisk.arf $(TMP)fdisk.lnk - $(QUIET)$(COPY) $(TMP)fdisk.arf $(TMP)fdisk.lk - $(QUIET)$(SDLD) $(SDLDFLG) -nf $(TMP)fdisk.lnk - $(QUIET)$(COPY) $(COPYFLG) fdisk.ihx $(OBJ)fdisk.ihx - $(QUIET)$(COPY) $(COPYFLG) fdisk.map map - -$(OBJ)fdisk.rel: $(SRC)fdisk.c $(INCFILES) $(MK) - $(QUIET)$(SDCC) -I inc $(SDCCFLG) $(SRC)fdisk.c - $(QUIET)$(COPY) $(COPYFLG) fdisk.rel $(OBJ) - -############################################################################ -# Dynamically created linker command file for fdisk utility (CP/M version) # -# Now uses macro controlled ECHO feature # -############################################################################ -$(TMP)fdisk.arf: $(MK) - $(ECHO) -mjx > $(TMP)fdisk.arf - $(ECHO) -i fdisk.ihx >> $(TMP)fdisk.arf - $(ECHO) -k $(SDCCLIB) >> $(TMP)fdisk.arf - $(ECHO) -l z80 >> $(TMP)fdisk.arf - $(ECHO) $(OBJ)cpm0.rel >> $(TMP)fdisk.arf - $(ECHO) $(OBJ)fdisk.rel >> $(TMP)fdisk.arf - $(ECHO) $(OBJ)cpmbdos.rel >> $(TMP)fdisk.arf - $(ECHO) $(OBJ)cprintf.rel >> $(TMP)fdisk.arf - $(ECHO) -e >> $(TMP)fdisk.arf - - -#----------------------------------------------------------- - -# Also build host version of fdisk for testing purposes - -$(BIN)fdisk$(EXE): $(SRC)fdisk.c $(MK) - $(QUIET)$(TCC) $(TCCFLG) $(SRC)fdisk.c -o $(BIN)fdisk - -############################################################ - -# Build CP/M-80 Command File Structure Files - -$(OBJ)cpm0.rel: $(SRC)cpm0.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)cpm0.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)cpm0.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)cpm0.lst $(LST) - -$(OBJ)cpmbdos.rel: $(SRC)cpmbdos.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)cpmbdos.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)cpmbdos.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)cpmbdos.lst $(LST) - -############################################################ - -# Build ROM Image structure files - -$(OBJ)crt0.rel: $(SRC)crt0.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)crt0.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)crt0.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)crt0.lst $(LST) - -$(OBJ)crt0jplp.rel: $(SRC)crt0jplp.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)crt0jplp.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)crt0jplp.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)crt0jplp.lst $(LST) - -$(OBJ)crt0scrm.rel: $(SRC)crt0scrm.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)crt0scrm.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)crt0scrm.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)crt0scrm.lst $(LST) - -$(OBJ)bdosb01.rel: $(SRC)bdosb01.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)bdosb01.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)bdosb01.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)bdosb01.lst $(LST) - -$(OBJ)ccpb03.rel: $(SRC)ccpb03.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)ccpb03.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)ccpb03.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)ccpb03.lst $(LST) - -# -# Assemble hardware control code for SBC V2 -# -$(OBJ)cbios.rel: $(SRC)cbios.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)cbios.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)cbios.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)cbios.lst $(LST) - -# -# Assemble a monitor program for the SBC V2 -# -$(OBJ)dbgmon.rel: $(SRC)dbgmon.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)dbgmon.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)dbgmon.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)dbgmon.lst $(LST) - -########################################################### - -# Build host based tools ( dwgh2b, jrch2b, load, verify) - -$(DWGH2B): $(SRC)dwgh2b.c $(MK) - $(QUIET)$(TCC) $(TCCFLG) $(SRC)dwgh2b.c -o $(BIN)dwgh2b$(EXE) - -# -# Compile John Coffman's hex2bin program -# -$(JRCH2B): $(SRC)jrch2b.c $(MK) - $(QUIET)$(TCC) $(TCCFLG) $(SRC)jrch2b.c -o $(BIN)jrch2b$(EXE) - $(QUIET)$(COPY) $(COPYFLG) $(BIN)jrch2b $(BIN)jrcb2h - -# -# Compile Doug's "load" program -# -$(LOAD): $(SRC)load.c $(MK) - $(QUIET)$(TCC) $(TCCFLG) $(SRC)load.c -o $(BIN)load$(EXE) - -$(SYSGEN): $(SRC)sysgen.c $(MK) - $(QUIET)$(TCC) $(TCCFLG) $(SRC)sysgen.c -o $(BIN)sysgen$(EXE) - -# -# Compile Doug's verif program that compares binary file regions -# -$(VERIFY): $(SRC)verify.c Makefile $(MK) - $(QUIET)$(TCC) $(TCCFLG) $(SRC)verify.c -o $(BIN)verify - -$(BIN)lechocr: $(SRC)lechocr.c $(MK) -# $(QUIET)$(TCC) $(TCCFLG) $(SRC)lechocr.c -o $(BIN)lechocr - $(QUIET)$(TCC) $(TCCFLG) $(SRC)lechocr.c - $(QUIET)$(COPY) lechocr.exe $(BIN) - -$(BIN)lecholf: $(SRC)lecholf.c $(MK) -# $(QUIET)$(TCC) $(TCCFLG) $(SRC)lecholf.c -o $(BIN)lecholf - $(QUIET)$(TCC) $(TCCFLG) $(SRC)lecholf.c - $(COPY) lecholf.exe $(BIN) - -$(BIN)lechocrlf: $(SRC)lechocrlf.c $(MK) - $(QUIET)$(TCC) $(TCCFLG) $(SRC)lechocrlf.c -o $(BIN)lechocrlf - -$(BIN)lecholfcr: $(SRC)lecholfcr.c $(MK) -# $(QUIET)$(TCC) $(TCCFLG) $(SRC)lecholfcr.c -o $(BIN)lecholfcr - $(QUIET)$(TCC) $(TCCFLG) $(SRC)lecholfcr.c -o $(BIN)lecholfcr - -############################################################ - -# Builder specific utility rules - -dwginstall: - $(COPY) $(COMFILES) ~/Documents/devobox/cdrive - -############################################################ - -# -# Delete all dynamically generated files that don't need to be -# saved. -# -clean: - $(QUIET)$(DEL) $(DELFLG) *.hex *.ihx *.lst *.rel *.rst *.lnk *.lk - $(QUIET)$(DEL) $(DELFLG) *.sym *.map *.noi *.asm *.com *.ini *.bin - $(QUIET)$(DEL) $(DELFLG) obj$(DELIM)*.* - $(QUIET)$(DEL) $(DELFLG) bin$(DELIM)*.* - $(QUIET)$(DEL) $(DELFLG) com$(DELIM)*.* - $(QUIET)$(DEL) $(DELFLG) rom$(DELIM)*.* - $(QUIET)$(DEL) $(DELFLG) tmp$(DELIM)*.* - $(QUIET)$(DEL) $(DELFLG) map$(DELIM)*.* - $(QUIET)$(DEL) $(DELFLG) lst$(DELIM)*.* - -################## -# eof - Makefile # -################## diff --git a/doug/exp/makefile.mac b/doug/exp/makefile.mac deleted file mode 100755 index 506bc8c0..00000000 --- a/doug/exp/makefile.mac +++ /dev/null @@ -1,26 +0,0 @@ -# ubios/makefile.mac 8/8/2011 dwg - - -DELIM = / -SPREFIX = /Developer/sdcc -SDAS = $(SPREFIX)/bin/sdasz80 -SDASFLG = -plosff -Iinc -SDCC = $(SPREFIX)/bin/sdcc -SDCCFLG = -c -mz80 -D__SDCC__=1 -I inc -SDCCLIB = $(SPREFIX)/share/sdcc/lib/z80 -SDLD = $(SPREFIX)/bin/sdldz80 -SDLDFLG = -TPREFIX = -TCC = gcc -TCCFLG = -I inc -COPY = cp -DEL = rm -DELFLG = -f -# use native ECHO o Mac OS X -ECHO = echo -REN = mv -EXE = - -include common.mak - - - diff --git a/doug/exp/makefile.win b/doug/exp/makefile.win deleted file mode 100755 index c324b33d..00000000 --- a/doug/exp/makefile.win +++ /dev/null @@ -1,24 +0,0 @@ - -DELIM = \ -SDRIVE = C: -SPREFIX = $(SDRIVE)\sdcc -SDAS = $(SPREFIX)\bin\sdasz80 -SDASFLG = -plosff -SDCC = $(SPREFIX)\bin\sdcc -SDCCFLG = -c -mz80 -D__SDCC__=1 -I inc -SDCCLIB = $(SPREFIX)\lib\z80 -SDLD = $(SPREFIX)\bin\sdldz80 -SDLDFLG = -TPREFIX = -TCC = gcc -TCCOPT = -I inc -COPY = copy -DEL = erase -DELFLG = /Q -REN = rename -ECHO = $(BIN)lecholf -EXE = .exe - -.include common.mak - - diff --git a/doug/inc/agm1264f.h b/doug/inc/agm1264f.h deleted file mode 100755 index 0adab14d..00000000 --- a/doug/inc/agm1264f.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * - * agm1264f.h 5/14/2011 dwg - - * 8 lines of 21 characters - * - */ - -/* - - 1 2 - 123456789012345678901 - --------------------- -1 |1234 11223344 1234 | -2 | | -3 | | -4 | | -5 | | -6 | | -7 | | -8 | | - --------------------- - -/* This is a 7x5 character layout showing how much text data can be display on the agm1264f - 1 1 1 - 1 2 3 4 5 6 7 8 9 0 1 2 - 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567 - --------------------------------------------------------------------------------------------------------------------------------- - 0 | 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 | - 1 | 2 | - 2 | 3 | - 3 | 4 | - 4 | 5 | - 5 | 6 | - 6 | 72345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 | - 7 | | - 8 | 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 | - 9 | 2 | -10 | 3 | - 1 | 4 | - 2 | 5 | - 3 | 6 | - 4 | 72345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 | - 5 | | - 6 | 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 | - 7 | 2 | - 8 | 3 | - 9 | 4 | -20 | 5 | - 1 | 6 | - 2 | 72345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 | - 3 | | - 4 | 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 | - 5 | 2 | - 6 | 3 | | - 7 | 4 | - 8 | 5 | - 9 | 6 | -30 | 72345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 | - 1 | | - 2 | 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 | - 3 | 2 | - 4 | 3 | - 5 | 4 | - 6 | 5 | - 7 | 6 | - 8 | 72345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 | - 9 | | -40 | 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 | - 1 | 2 | - 2 | 3 | - 3 | 4 | - 4 | 5 | - 5 | 6 | - 6 | 72345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 | - 7 | | - 8 | 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 | - 9 | 2 | -50 | 3 | - 1 | 4 | - 2 | 5 | - 3 | 6 | - 4 | 72345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 | - 5 | | - 6 | 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 | - 7 | 2 | - 8 | 3 | - 9 | 4 | -60 | 5 | - 1 | 6 | - 2 | 72345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 | - 3 | | - --------------------------------------------------------------------------------------------------------------------------------- -*/ - - diff --git a/doug/inc/cpmbdos.h b/doug/inc/cpmbdos.h deleted file mode 100755 index ce3f2451..00000000 --- a/doug/inc/cpmbdos.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * CP/M-80 v2.2 BDOS Interfaces - * Copyright (C) Douglas W. Goodall - * For Non-Commercial use by N8VEM - * 5/10/2011 dwg - initial version -*/ -#define EXIT_SUCCESS 0 -#define EXIT_FAILURE 1 - -#define C_READ 1 -#define C_WRITE 2 -#define A_READ 3 -#define A_WRITE 4 -#define L_WRITE 5 -#define C_RAWIO 6 -#define GETIOBYTE 7 -#define SETIOBYTE 8 -#define C_WRITESTR 9 -#define C_READSTR 10 -#define F_OPEN 15 -#define F_CLOSE 16 -#define F_DELETE 19 -#define F_READ 20 -#define F_WRITE 21 -#define F_MAKE 22 -#define F_RENAME 23 -#define DRV_LOGINVEC 24 -#define DRV_GET 25 -#define F_DMAOFF 26 -#define DRV_ALLOCVEC 27 -#define DRV_SETRO 28 -#define DRV_ROVEC 29 -#define F_ATTRIB 30 -#define DRV_DPB 31 -#define F_USERNUM 32 -#define F_READRAND 33 -#define F_WRITERAND 34 -#define F_SIZE 35 -#define F_RANDREC 36 -#define DRV_RESET 37 -#define F_WRITEZF 40 - - -struct BDOSCALL { - unsigned char func8; - unsigned int parm16; -}; - -unsigned char cpmbdos(struct BDOSCALL *p); - -struct FCB { - unsigned char drive; - char filename[8]; - char filetype[3]; - unsigned char ex; - unsigned char s1; - unsigned char s2; - unsigned char rc; - unsigned char al[16]; - unsigned char cr; - unsigned char r0; - unsigned char r1; - unsigned char r2; -}; - -struct READSTR { - unsigned char size; - unsigned char len; - char bytes[80]; - } rsbuffer; - -struct BDOSCALL readstr = { C_READSTR, { (unsigned int)&rsbuffer } }; - -char * mygets(char *p) -{ - memset(rsbuffer.bytes,0,sizeof(rsbuffer.bytes)); - rsbuffer.size = sizeof(rsbuffer.bytes); - rsbuffer.len = 0; - cpmbdos(&readstr); - rsbuffer.bytes[rsbuffer.len] = '\n'; - strcpy(p,rsbuffer.bytes); - return p; -} - -#define gets mygets - -/*****************/ -/* eof - cpm80.h */ -/*****************/ diff --git a/doug/inc/cprintf.h b/doug/inc/cprintf.h deleted file mode 100755 index 925275e3..00000000 --- a/doug/inc/cprintf.h +++ /dev/null @@ -1,7 +0,0 @@ -/* cprintf.h */ - -int cprintf(const char * fmt, ...); - -#define printf cprintf - - diff --git a/doug/inc/diskio.h b/doug/inc/diskio.h deleted file mode 100755 index 2235f5b3..00000000 --- a/doug/inc/diskio.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * diskio.h - * - */ - -__sfr __at (DISKIO_IDE + 0x00) pIDELO; -__sfr __at (DISKIO_IDE + 0x01) pIDEERR; -__sfr __at (DISKIO_IDE + 0x02) pIDESECTC; -__sfr __at (DISKIO_IDE + 0x03) pIDESECTN; -__sfr __at (DISKIO_IDE + 0x04) pIDECYLLO; -__sfr __at (DISKIO_IDE + 0x05) pIDECYLHI; -__sfr __at (DISKIO_IDE + 0x06) pIDEHEAD; -__sfr __at (DISKIO_IDE + 0x07) pIDESTTS; -__sfr __at (DISKIO_IDE + 0x08) pIDEHI; -__sfr __at (DISKIO_IDE + 0x0E) pIDECTRL; - -__sfr __at (DISKIO_FLP + 0x06) pFMSR; -__sfr __at (DISKIO_FLP + 0x07) pFDATA; -__sfr __at (DISKIO_FLP + 0x0A) pFLATCH; -__sfr __at (DISKIO_FLP + 0x0C) pFDMA; - -/* - * - * eof - diskio.h - * - */ - - diff --git a/doug/inc/ds1302.h b/doug/inc/ds1302.h deleted file mode 100755 index 10ea3685..00000000 --- a/doug/inc/ds1302.h +++ /dev/null @@ -1,7 +0,0 @@ -/* - * - * ds1302 Dallas Real Time Clock module - * - */ - - diff --git a/doug/inc/i8255.h b/doug/inc/i8255.h deleted file mode 100755 index 458d8349..00000000 --- a/doug/inc/i8255.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * i8255.h Intel 8255 - * - */ - - -void uart_init(U8 baud); -U8 uart_conin(void); -void uart_conout(U8 data); - -/* - * - * eof - i8255.h - * - */ diff --git a/doug/inc/jrctypes.h b/doug/inc/jrctypes.h deleted file mode 100755 index c97ed7eb..00000000 --- a/doug/inc/jrctypes.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef __MYTYPES_H -#define __MYTYPES_H 1 - -typedef unsigned char byte; -typedef unsigned short word; -typedef unsigned long dword; - - -#ifdef __SDCC__ -#define outp(port,byte) port = (byte) -#define inp(port) (port) -#endif - -#define nelem(x) (sizeof(x)/sizeof(x[0])) - -#endif /* __MYTYPES_H */ diff --git a/doug/inc/ns16550.h b/doug/inc/ns16550.h deleted file mode 100755 index 40298323..00000000 --- a/doug/inc/ns16550.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * n16550.h National 16550 - * - */ - -#define UART_DLAB 0x80 -#define UART_BAUD_9600 12 -#define UART_RDA 0x01 -#define UART_TBE 0x20 - -/* - * - * eof - n16550.h - * - */ diff --git a/doug/inc/ns16550.inc b/doug/inc/ns16550.inc deleted file mode 100755 index ba166726..00000000 --- a/doug/inc/ns16550.inc +++ /dev/null @@ -1,8 +0,0 @@ -; ns16550.inc 8/7/2011 dwg - National 16550 - -UART_DLAB = 0x80 -UART_BAUD_9600 = 12 -UART_RDA = 0x01 -UART_TBE = 0x20 - -; eof - ns16550.inc diff --git a/doug/inc/portab.h b/doug/inc/portab.h deleted file mode 100755 index 5ad24e41..00000000 --- a/doug/inc/portab.h +++ /dev/null @@ -1,12 +0,0 @@ -/************/ -/* portab.h */ -/************/ - -#define TRUE 1 -#define FALSE 0 - -#define U8 unsigned char - -/******************/ -/* eof - portab.h */ -/******************/ diff --git a/doug/inc/sbcv2.h b/doug/inc/sbcv2.h deleted file mode 100755 index d6607a5d..00000000 --- a/doug/inc/sbcv2.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * sbcv2.h - Macros describing the N8VEM SBC V2 - * - */ - -#define SBCV2 - -/* set i/o base to first block of 32 addresses - possible are 0x00 0x20 0x40 0x60 0x80 0xA0 0xC0 0xE0 - depending oon setting of dip switches on board -*/ - -#define SBCV2_IO_BASE 0x00 -#define UART_IO_BASE ( SBCV2_IO_BASE + 0x68 ) - -__sfr __at (UART_IO_BASE+0) rUART_RBR; -__sfr __at (UART_IO_BASE+0) wUART_THR; -__sfr __at (UART_IO_BASE+0) wUART_DIV_LO; -__sfr __at (UART_IO_BASE+1) wUART_DIV_HI; - -__sfr __at (UART_IO_BASE+1) wUART_IER; -__sfr __at (UART_IO_BASE+2) rUART_IIR; -__sfr __at (UART_IO_BASE+3) wUART_LCR; -__sfr __at (UART_IO_BASE+4) wUART_MCR; -__sfr __at (UART_IO_BASE+5) rUART_LSR; -__sfr __at (UART_IO_BASE+6) rUART_MSR; -__sfr __at (UART_IO_BASE+7) wUART_FCR; - - -#define DISKIO_IDE 0x20 - -#define DISKIO_FLP 0x30 - -#define PPORT 0x60 - -#define MPCL 0x70 -__sfr __at (MPCL + 0x08) pMPCL_RAM; -__sfr __at (MPCL + 0x0c) pMPCL_ROM; - -#define RAMTARG_CPM 0x2000 -#define ROMSTART_CPM 0x0000 -#define CCPSIZ_CPM 0x2000 - -#define LOADER_ORG 0x0000 -#define CPM_ORG 0x0A00 -#define MON_ORG 0x3800 -#define ROM_G 0x5000 -#define ROM_F 0x8000 -/* -#define VDU_DRV 0xF8100 -*/ - diff --git a/doug/inc/scsi2ide.h b/doug/inc/scsi2ide.h deleted file mode 100755 index 6f8684c4..00000000 --- a/doug/inc/scsi2ide.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * - * scsi2ide.h - Macros describing the N8VEM SCSI2IDE - * Friday July 29, 2011 Douglas W. Goodall - * - */ - -#define SCSI2IDE - -/* set i/o base to first block of 32 addresses - possible are 0x00 0x20 0x40 0x60 0x80 0xA0 0xC0 0xE0 - depending oon setting of dip switches on board -*/ - -#define SCSI2IDE_IO_BASE 0x00 - -#define IDE_IO_BASE ( SCSI2IDE_IO_BASE + 0 ) -#define SCSI_IO_BASE ( SCSI2IDE_IO_BASE + 8 ) -#define UART_IO_BASE ( SCSI2IDE_IO_BASE + 16 ) -#define DACK_IO_BASE ( SCSI2IDE_IO_BASE + 24 ) - -__sfr __at (UART_IO_BASE+0) rUART_RDR; -__sfr __at (UART_IO_BASE+0) wUART_TDR; -__sfr __at (UART_IO_BASE+0) wUART_DIV_LO; -__sfr __at (UART_IO_BASE+1) wUART_DIV_HI; -__sfr __at (UART_IO_BASE+1) wUART_IER; -__sfr __at (UART_IO_BASE+2) rUART_IIR; -__sfr __at (UART_IO_BASE+3) wUART_LCR; -__sfr __at (UART_IO_BASE+4) wUART_MCR; -__sfr __at (UART_IO_BASE+5) rUART_LSR; -__sfr __at (UART_IO_BASE+6) rUART_MSR; -__sfr __at (UART_IO_BASE+7) wUART_FCR; - -__sfr __at (SCSI_IO_BASE+0) rSCSI_CSCSID; -__sfr __at (SCSI_IO_BASE+0) wSCSI_OD; -__sfr __at (SCSI_IO_BASE+1) rwSCSI_IC; -__sfr __at (SCSI_IO_BASE+2) rwSCSI_M; -__sfr __at (SCSI_IO_BASE+3) rwSCSI_TC; -__sfr __at (SCSI_IO_BASE+4) rSCSI_CSCSIBS; -__sfr __at (SCSI_IO_BASE+4) wSCSI_SE; -__sfr __at (SCSI_IO_BASE+5) rSCSI_BS; -__sfr __at (SCSI_IO_BASE+5) wSCSI_SDMAS; -__sfr __at (SCSI_IO_BASE+6) rSCSI_ID; -__sfr __at (SCSI_IO_BASE+6) wSCSI_SDMATR; -__sfr __at (SCSI_IO_BASE+7) rSCSI_RPI; -__sfr __at (SCSI_IO_BASE+7) wSCSI_SDMAIR; - diff --git a/doug/inc/scsi2ide.inc b/doug/inc/scsi2ide.inc deleted file mode 100755 index a3eb74af..00000000 --- a/doug/inc/scsi2ide.inc +++ /dev/null @@ -1,20 +0,0 @@ -; scsi2ide.inc 8/7/2011 dwg - macros describing the N8VEM SCSI2IDE - -SCSI2IDE_IO_BASE = 0 - -UART_IO_BASE = SCSI2IDE_IO_BASE+16 - -rUART_RDR = UART_IO_BASE + 0 -wUART_TDR = UART_IO_BASE + 0 -wUART_DIV_LO = UART_IO_BASE + 0 -wUART_DIV_HI = UART_IO_BASE + 1 -wUART_IER = UART_IO_BASE + 1 -rUART_IIR = UART_IO_BASE + 2 -wUART_LCR = UART_IO_BASE + 3 -wUART_MCR = UART_IO_BASE + 4 -rUART_LSR = UART_IO_BASE + 5 -rUART_MSR = UART_IO_BASE + 6 -wUART_FCR = UART_IO_BASE + 7 - -; eof - scsi2ide.inc - diff --git a/doug/inc/z53c80.h b/doug/inc/z53c80.h deleted file mode 100755 index 7ef720ef..00000000 --- a/doug/inc/z53c80.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * z53c80.h Zilog Z53C8003VSC - * - */ - -/* -__sfr __at (UART + 0) pPORTA; -__sfr __at (UART + 1) pPORTB; -__sfr __at (UART + 2) pPORTC; -__sfr __at (UART + 3) pCNTRL; -*/ - -void scsi_init(void); - -/* -U8 uart_conin(void); -void uart_conout(U8 data); -*/ - -/* - * - * eof - z53c80.h - * - */ diff --git a/doug/makefile.w64 b/doug/makefile.w64 deleted file mode 100755 index 675067bc..00000000 --- a/doug/makefile.w64 +++ /dev/null @@ -1,550 +0,0 @@ -######################################################## -# Makefile for Doug's Unified BIOS 5/30/2011 # -# The BIOS and associated utilities are generated # -# using the Small Device C Compiler (SDCC) & tools # -# With multiplatform enhancements by John Coffman # -# # -# sdcc.l00 added because stupid Windoze 'echo' appends # -# a confusing SPACE to the end of every line. # -######################################################## - -##################################################### -# SPREFIX tells where the SDCC package in installed # -# The SDCC package is used to assemble Z80 portions # -# of the software such as the ROM and perhaps some # -# .COM files such as FDISK. # -##################################################### - -################################################################# -# TPREFIX tells where the host development tools are installed. # -# The host tools are used to manipulate the Z80 objects after # -# the basic assemblies and compilations have been completed. # -################################################################# - -################################################################### -# SDCC is not available on the DOS host, so something else may be # -# used at the descretion of the builder. (TASM for instance). # -################################################################### - -################################################################### -# The COPY, DEL and RENAME macros are used to customize the build # -# rules for the host enviroonment. # -################################################################### - -#------------------------------------------- -# Choose one only, then Make will work for -# your platform. - -#CFG = $(shell uname) -# Mac OS X returns 'Darwin' -# Linux returns 'Linux' - -#CFG = dos -#CFG = linux -#CFG = macosx -CFG = windows - -#------------------------------------------- - -DELIM = \ -SDRIVE = C: -SPREFIX = $(SDRIVE)\sdcc -SDAS = $(SPREFIX)\bin\sdasz80 -SDASFLG = -plosff -SDCC = $(SPREFIX)\bin\sdcc -SDCCFLG = -c -mz80 -D__SDCC__=1 -I inc -SDCCLIB = $(SPREFIX)\lib\z80 -SDLD = $(SPREFIX)\bin\sdldz80 -SDLDFLG = -TPREFIX = -TCC = gcc -TCCOPT = -I inc -COPY = copy -DEL = erase -DELFLG = /Q -REN = rename - -# This is special handling for John Coffman to get around funky windows -# behavior where echo adds spurious space o end f line -# ECHO = { lecho | lechocr | lecholf | lechocrlf | lecholfcr } - -#ECHO = $(BIN)$(DELIM)lechocr -ECHO = $(BIN)lecholf - -EXE = .exe - - -#------------------------------------------- -############################################################ - -# Misc other macros - -BIN = bin$(DELIM) -COM = com$(DELIM) -INC = inc$(DELIM) -LIB = lib$(DELIM) -LST = lst$(DELIM) -MAP = map$(DELIM) -OBJ = obj$(DELIM) -REF = ref$(DELIM) -ROM = rom$(DELIM) -SRC = src$(DELIM) -TMP = tmp$(DELIM) - -# CP/M-80 v2.2 Command files written in SDCC -COMFILES = $(COM)copyfile.com $(COM)fdisk.com - -# Components used by CP/M-80 v2.2 Command files -COMRELS = $(OBJ)cpm0.rel $(OBJ)cpmbdos.rel $(OBJ)cprintf.rel - -# Components of ROM image containing CP/M for SBC V2 -CPMRELS = $(OBJ)crt0.rel $(OBJ)dbgmon.rel $(OBJ)bdosb01.rel $(OBJ)ccpb03.rel $(OBJ)cbios.rel - -# Components that control hardware in SBC V2 -SBCV2HW = - -# Components that control hardware in the SCSI2IDE -SCSI2IDEHW = $(OBJ)z53c80.rel - -FDISK = $(BIN)fdisk$(EXE) -DWGH2B = $(BIN)dwgh2b$(EXE) -INCFILES = $(INC)cpmbdos.h $(INC)cprintf.h $(INC)portab.h -JRCH2B = $(BIN)jrch2b$(EXE) -LOAD = $(BIN)load$(EXE) -MK = Makefile -#QUIET = @ - -# ROM images for SBC V2 and N8 -ROMFILES = $(ROM)scsi2ide.rom $(ROM)baseline.rom $(ROM)n8.rom -SCSI2IDE = $(ROM)scsi2ide.rom - -SYSGEN = $(BIN)sysgen$(EXE) -VERIFY = $(BIN)verify$(EXE) - -# C programs compiled on host system used in build -TOOLS = $(FDISK) $(DWGH2B) $(LOAD) $(JRCH2B) $(SYSGEN) - -# Versions of 'echo' compiled on host system -ETOOLS = $(BIN)lechocr.exe $(BIN)lecholf.exe $(BIN)lechocrlf.exe $(BIN)lecholfcr.exe - -# dribdos.rel is not part of the production set yet -##TEST = dribdos.rel - -############################################################ - -all: $(ETOOLS) $(TOOLS) $(BINFILES) $(COMFILES) $(CPMFILES) $(ROMFILES) - -#all: $(TEST) $(ROMFILES) $(COMFILES) - -etools: $(ETOOLS) -roms: $(ROMFILES) -scsi2ide: $(SCSI2IDE) - -############################################################ - -# A test assembly of DRI source code for BDOS (from SIMH) -dribdos.rel: $(SRC)dribdos.s - $(QUIET)$(SDAS) $(SDASFLG) dribdos.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)dribdos.lst $(LST) - -############################################################ -############################################################ - -# Build SCSI2IDE ROM image - -$(ROM)scsi2ide.rom: $(OBJ)scsi2ide.bin $(MK) - $(QUIET)$(COPY) $(OBJ)scsi2ide.bin $(ROM)scsi2ide.rom - $(QUIET)$(DEL) $(DELFLG) scsi2ide.* - -$(OBJ)scsi2ide.bin: $(OBJ)scsi2ide.hex $(DWGH2B) $(MK) - $(QUIET)$(DWGH2B) $(OBJ)scsi2ide - -$(OBJ)scsi2ide.hex: $(OBJ)scsi2ide.ihx $(MK) - $(QUIET)$(COPY) $(OBJ)scsi2ide.ihx $(OBJ)scsi2ide.hex - -$(OBJ)scsi2ide.ihx: $(CPMRELS) $(SCSI2IDEHW) $(OBJ)scsi2ide.rel $(TMP)scsi2ide.arf $(MK) - $(QUIET)$(COPY) $(TMP)scsi2ide.arf $(TMP)scsi2ide.lk - $(QUIET)$(COPY) $(TMP)scsi2ide.arf $(TMP)scsi2ide.lnk - $(QUIET)$(SDLD) $(SDLDFLG) -nf $(TMP)scsi2ide.lnk - $(QUIET)$(COPY) $(COPYFLG) scsi2ide.ihx $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) scsi2ide.map $(MAP) - -######################################################### -# Dynamically generate linker control file for scsi2ide # -# (now uses the macro controlled ECHO feature # -######################################################### -$(TMP)scsi2ide.arf: $(MK) - $(ECHO) -mjx > $(TMP)scsi2ide.arf - $(ECHO) -i scsi2ide.ihx >> $(TMP)scsi2ide.arf - $(ECHO) -k $(SDCCLIB) >> $(TMP)scsi2ide.arf - $(ECHO) -l z80 >> $(TMP)scsi2ide.arf -# $(ECHO) -b _CCPB03 = 0xD000 >> $(TMP)scsi2ide.arf -# $(ECHO) -b _BDOSB01 = 0xD800 >> $(TMP)scsi2ide.arf -# $(ECHO) -b _CBIOS = 0xE600 >> $(TMP)scsi2ide.arf -# $(ECHO) -b _DBGMON = 0x8000 >> $(TMP)scsi2ide.arf - $(ECHO) $(OBJ)crt0.rel >> $(TMP)scsi2ide.arf - $(ECHO) $(OBJ)scsi2ide.rel >> $(TMP)scsi2ide.arf -# $(ECHO) $(OBJ)dbgmon.rel >> $(TMP)scsi2ide.arf -# $(ECHO) $(OBJ)ccpb03.rel >> $(TMP)scsi2ide.arf -# $(ECHO) $(OBJ)bdosb01.rel >> $(TMP)scsi2ide.arf -# $(ECHO) $(OBJ)cbios.rel >> $(TMP)scsi2ide.arf - $(ECHO) -e >> $(TMP)scsi2ide.arf - -######################################################## -# Compile C portion of the scsi2ide EEPROM Image -$(OBJ)scsi2ide.rel: $(SRC)scsi2ide.c $(MK) - $(QUIET)$(SDCC) $(SDCCFLG) -c $(SRC)scsi2ide.c - $(QUIET)$(COPY) $(COPYFLG) scsi2ide.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) scsi2ide.lst $(LST) - - -############################################################ -############################################################ - -# Build SBC V2 ROM image - -$(ROM)baseline.rom: $(OBJ)baseline.bin $(MK) - $(QUIET)$(COPY) $(OBJ)baseline.bin $(ROM)baseline.rom - $(QUIET)$(DEL) $(DELFLG) baseline.* - -$(OBJ)baseline.bin: $(OBJ)baseline.hex $(DWGH2B) $(MK) - $(QUIET)$(DWGH2B) $(OBJ)baseline - -$(OBJ)baseline.hex: $(OBJ)baseline.ihx $(MK) - $(QUIET)$(COPY) $(OBJ)baseline.ihx $(OBJ)baseline.hex - -$(OBJ)baseline.ihx: $(CPMRELS) $(SBCV2HW) $(OBJ)baseline.rel $(TMP)baseline.arf $(MK) - $(QUIET)$(COPY) $(TMP)baseline.arf $(TMP)baseline.lk - $(QUIET)$(COPY) $(TMP)baseline.arf $(TMP)baseline.lnk - $(QUIET)$(SDLD) $(SDLDFLG) -nf $(TMP)baseline.lnk - $(QUIET)$(COPY) $(COPYFLG) baseline.ihx $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) baseline.map $(MAP) - -######################################################### -# Dynamically generate linker control file for baseline # -# (now uses the macro controlled ECHO feature # -######################################################### -$(TMP)baseline.arf: $(MK) - $(ECHO) -mjx > $(TMP)baseline.arf - $(ECHO) -i baseline.ihx >> $(TMP)baseline.arf - $(ECHO) -k $(SDCCLIB) >> $(TMP)baseline.arf - $(ECHO) -l z80 >> $(TMP)baseline.arf - $(ECHO) -b _CCPB03 = 0xD000 >> $(TMP)baseline.arf - $(ECHO) -b _BDOSB01 = 0xD800 >> $(TMP)baseline.arf - $(ECHO) -b _CBIOS = 0xE600 >> $(TMP)baseline.arf - $(ECHO) -b _DBGMON = 0x8000 >> $(TMP)baseline.arf - $(ECHO) $(OBJ)crt0.rel >> $(TMP)baseline.arf - $(ECHO) $(OBJ)baseline.rel >> $(TMP)baseline.arf - $(ECHO) $(OBJ)dbgmon.rel >> $(TMP)baseline.arf - $(ECHO) $(OBJ)ccpb03.rel >> $(TMP)baseline.arf - $(ECHO) $(OBJ)bdosb01.rel >> $(TMP)baseline.arf - $(ECHO) $(OBJ)cbios.rel >> $(TMP)baseline.arf - $(ECHO) -e >> $(TMP)baseline.arf - -######################################################## -# Compile C portion of the Baseline PROM Image -$(OBJ)baseline.rel: $(SRC)baseline.c $(MK) - $(QUIET)$(SDCC) $(SDCCFLG) -c $(SRC)baseline.c - $(QUIET)$(COPY) $(COPYFLG) baseline.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) baseline.lst $(LST) - -############################################################ - -# Build N8 ROM image - -# -# Save the resulting merged image in the Rom folder -# -$(ROM)n8.rom: $(OBJ)n8-romim.bin $(MK) - $(QUIET)$(COPY) $(OBJ)n8-romim.bin $(ROM)n8.rom - $(QUIET)$(DEL) $(DELFLG) n8.* - -# -# Convert the Intel hex file into a binary, similar -# to the results of the "copy /B ..." -# -$(OBJ)n8-romim.bin: $(OBJ)sysimage.hex $(REF)n8-romim.ref $(SYSGEN) $(HEX2BIN) $(MK) - $(QUIET)$(DWGH2B) $(OBJ)sysimage - $(QUIET)$(COPY) $(REF)n8-romim.ref $(OBJ)n8-romim.bin - $(QUIET)$(SYSGEN) -i $(OBJ)sysimage.bin $(OBJ)n8-romim.bin - -# -# Take the output of the linker and rename to the more -# recognizable .hex form and the expected name "sysimage.hex" -# -$(OBJ)sysimage.hex: $(OBJ)n8.ihx $(MK) - $(QUIET)$(COPY) $(OBJ)n8.ihx $(OBJ)sysimage.hex - -# -# Combine the independently assembled components into one piece -# and output Intel hex file (ihx) -# -$(OBJ)n8.ihx: $(OBJ)loadern8.rel $(OBJ)dbgmon.rel $(OBJ)ccpb03.rel $(OBJ)bdosb01.rel $(OBJ)cbiosn8.rel $(TMP)n8.arf $(MK) - $(QUIET)$(COPY) $(TMP)n8.arf $(TMP)n8.lk - $(QUIET)$(COPY) $(TMP)n8.arf $(TMP)n8.lnk - $(QUIET)$(SDLD) $(SDLDFLG) -nf $(TMP)n8.lnk - $(QUIET)$(COPY) $(COPYFLG) n8.ihx $(OBJ)n8.ihx - $(QUIET)$(COPY) $(COPYFLG) n8.map $(MAP) - -$(OBJ)cbiosn8.rel: $(SRC)cbiosn8.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)cbiosn8.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)cbiosn8.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)cbiosn8.lst $(LST) - -$(OBJ)loadern8.rel: $(SRC)loadern8.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)loadern8.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)loadern8.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)loadern8.lst $(LST) - -######################################################## -# Dynamically generate the linker control file for N8 # -# Now uses the macro controlled ECHO feature # -######################################################## -$(TMP)n8.arf: Makefile - $(ECHO) -mjx > $(TMP)n8.arf - $(ECHO) -i n8.ihx >> $(TMP)n8.arf - $(ECHO) -k $(SDCCLIB) >> $(TMP)n8.arf - $(ECHO) -l z80 >> $(TMP)n8.arf - $(ECHO) -b _CCPB03 = 0x0900 >> $(TMP)n8.arf - $(ECHO) -b _BDOSB01 = 0x1100 >> $(TMP)n8.arf - $(ECHO) -b _CBIOS = 0x1f00 >> $(TMP)n8.arf - $(ECHO) $(OBJ)loadern8.rel >> $(TMP)n8.arf - $(ECHO) $(OBJ)dbgmon.rel >> $(TMP)n8.arf - $(ECHO) $(OBJ)ccpb03.rel >> $(TMP)n8.arf - $(ECHO) $(OBJ)bdosb01.rel >> $(TMP)n8.arf - $(ECHO) $(OBJ)cbiosn8.rel >> $(TMP)n8.arf - $(ECHO) -e >> $(TMP)n8.arf - -############################################################ - -# Hardware specific assemblies (most likely used by BIOS's) - -# -# Assemble hardware control code for the Zilog Z53C8003V5C -# -$(OBJ)z53c80.rel: $(SRC)z53c80.c $(MK) - $(QUIET)$(SDCC) $(SDCCFLG) $(SRC)z53c80.c - $(QUIET)$(COPY) $(COPYFLG) z53c80.rel $(OBJ) - $(QUIET)$(DEL) $(DELFLG) z53c80.* - -# -# Compile ersatz printf routine for use in CP/M-80 command files -# -$(OBJ)cprintf.rel: $(SRC)cprintf.c $(MK) - $(QUIET)$(SDCC) $(SDCCFLG) $(SRC)cprintf.c - $(QUIET)$(COPY) $(COPYFLG) cprintf.rel obj - $(QUIET)$(DEL) $(DELFLG) cprintf.* - -############################################################ - -# Build CP/M 2.2 command files (copyfile.com, fdisk.com) - -#----------------------------------------------------------- - -$(COM)copyfile.com: $(OBJ)copyfile.com $(MK) - $(QUIET)$(COPY) $(OBJ)copyfile.com $(COM)copyfile.com - $(QUIET)$(DEL) $(DELFLG) copyfile.* - -$(OBJ)copyfile.com: $(OBJ)copyfile.hex $(LOAD) $(BINFILES) $(MK) - $(QUIET)$(LOAD) $(OBJ)copyfile - -$(OBJ)copyfile.hex: $(OBJ)copyfile.ihx $(MK) - $(QUIET)$(COPY) $(OBJ)copyfile.ihx $(OBJ)copyfile.hex - -$(OBJ)copyfile.ihx: $(OBJ)copyfile.rel $(COMRELS) $(TMP)copyfile.arf $(MK) - $(QUIET)$(COPY) $(TMP)copyfile.arf $(TMP)copyfile.lnk - - $(QUIET)$(SDLD) $(LOPTS) -nf $(TMP)copyfile.lnk - $(QUIET)$(COPY) $(COPYFLG) copyfile.ihx obj - $(QUIET)$(COPY) $(COPYFLG) copyfile.map map - -############################################################## -# Dynamicaly create linker command file for copyfile utility # -# Now uses the macro controlled ECHO feature # -############################################################## -$(TMP)copyfile.arf: Makefile - $(ECHO) -mjx > $(TMP)copyfile.arf - $(ECHO) -i copyfile.ihx >> $(TMP)copyfile.arf - $(ECHO) -k $(SDCCLIB) >> $(TMP)copyfile.arf - $(ECHO) -l z80 >> $(TMP)copyfile.arf - $(ECHO) $(OBJ)cpm0.rel >> $(TMP)copyfile.arf - $(ECHO) $(OBJ)copyfile.rel >> $(TMP)copyfile.arf - $(ECHO) $(OBJ)cpmbdos.rel >> $(TMP)copyfile.arf - $(ECHO) $(OBJ)cprintf.rel >> $(TMP)copyfile.arf - $(ECHO) -e >> $(TMP)copyfile.arf - -$(OBJ)copyfile.rel: $(SRC)copyfile.c $(MK) - $(QUIET)$(SDCC) $(SDCCFLG) $(SRC)copyfile.c - $(QUIET)$(COPY) copyfile.rel obj - $(QUIET)$(DEL) $(DELFLG) copyfile.rel -# ls obj - -#----------------------------------------------------------- - -# -# Use locally compiled 'load' command to covert Intel -# hex formal file to a binary CP/M-80 command file. -# -$(COM)fdisk.com: $(OBJ)fdisk.hex $(TOOLS) $(MK) - $(QUIET)$(BIN)load $(OBJ)fdisk - $(QUIET)$(COPY) $(COPYFLG) $(OBJ)fdisk.com com - $(QUIET)$(DEL) $(DELFLG) fdisk.* - -# -# rename 'ihx' output of linker to 'hex' - -$(OBJ)fdisk.hex: $(OBJ)fdisk.ihx $(MK) - $(QUIET)$(COPY) $(OBJ)fdisk.ihx $(OBJ)fdisk.hex - -$(OBJ)fdisk.ihx: $(OBJ)fdisk.rel $(TMP)fdisk.arf $(MK) - $(QUIET)$(COPY) $(TMP)fdisk.arf $(TMP)fdisk.lnk - $(QUIET)$(COPY) $(TMP)fdisk.arf $(TMP)fdisk.lk - $(QUIET)$(SDLD) $(SDLDFLG) -nf $(TMP)fdisk.lnk - $(QUIET)$(COPY) $(COPYFLG) fdisk.ihx $(OBJ)fdisk.ihx - $(QUIET)$(COPY) $(COPYFLG) fdisk.map map - -$(OBJ)fdisk.rel: $(SRC)fdisk.c $(INCFILES) $(MK) - $(QUIET)$(SDCC) -I inc $(SDCCFLG) $(SRC)fdisk.c - $(QUIET)$(COPY) $(COPYFLG) fdisk.rel $(OBJ) - -############################################################################ -# Dynamically created linker command file for fdisk utility (CP/M version) # -# Now uses macro controlled ECHO feature # -############################################################################ -$(TMP)fdisk.arf: $(MK) - $(ECHO) -mjx > $(TMP)fdisk.arf - $(ECHO) -i fdisk.ihx >> $(TMP)fdisk.arf - $(ECHO) -k $(SDCCLIB) >> $(TMP)fdisk.arf - $(ECHO) -l z80 >> $(TMP)fdisk.arf - $(ECHO) $(OBJ)cpm0.rel >> $(TMP)fdisk.arf - $(ECHO) $(OBJ)fdisk.rel >> $(TMP)fdisk.arf - $(ECHO) $(OBJ)cpmbdos.rel >> $(TMP)fdisk.arf - $(ECHO) $(OBJ)cprintf.rel >> $(TMP)fdisk.arf - $(ECHO) -e >> $(TMP)fdisk.arf - - -#----------------------------------------------------------- - -# Also build host version of fdisk for testing purposes - -$(BIN)fdisk$(EXE): $(SRC)fdisk.c $(MK) - $(QUIET)$(TCC) $(TCCOPT) $(SRC)fdisk.c -o $(BIN)fdisk - -############################################################ - -# Build CP/M-80 Command File Structure Files - -$(OBJ)cpm0.rel: $(SRC)cpm0.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)cpm0.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)cpm0.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)cpm0.lst $(LST) - -$(OBJ)cpmbdos.rel: $(SRC)cpmbdos.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)cpmbdos.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)cpmbdos.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)cpmbdos.lst $(LST) - -############################################################ - -# Build ROM Image structure files - -$(OBJ)crt0.rel: $(SRC)crt0.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)crt0.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)crt0.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)crt0.lst $(LST) - -$(OBJ)bdosb01.rel: $(SRC)bdosb01.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)bdosb01.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)bdosb01.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)bdosb01.lst $(LST) - -$(OBJ)ccpb03.rel: $(SRC)ccpb03.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)ccpb03.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)ccpb03.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)ccpb03.lst $(LST) -# -# Assemble hardware control code for SBC V2 -# -$(OBJ)cbios.rel: $(SRC)cbios.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)cbios.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)cbios.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)cbios.lst $(LST) - -# -# Assemble a monitor program for the SBC V2 -# -$(OBJ)dbgmon.rel: $(SRC)dbgmon.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)dbgmon.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)dbgmon.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)dbgmon.lst $(LST) - -########################################################### - -# Build host based tools ( dwgh2b, jrch2b, load, verify) - -$(DWGH2B): $(SRC)dwgh2b.c $(MK) - $(QUIET)$(TCC) $(TCCOPT) $(SRC)dwgh2b.c -o $(BIN)dwgh2b$(EXE) - -# -# Compile John Coffman's hex2bin program -# -$(JRCH2B): $(SRC)jrch2b.c $(MK) - $(QUIET)$(TCC) $(TCCOPT) $(SRC)jrch2b.c -o $(BIN)jrch2b$(EXE) -# $(QUIET)$(COPY) $(COPYFLG) $(BIN)jrch2b $(BIN)jrcb2h - -# -# Compile Doug's "load" program -# -$(LOAD): $(SRC)load.c $(MK) - $(QUIET)$(TCC) $(TCCOPT) $(SRC)load.c -o $(BIN)load$(EXE) - -$(SYSGEN): $(SRC)sysgen.c $(MK) - $(QUIET)$(TCC) $(TCCOPT) $(SRC)sysgen.c -o $(BIN)sysgen$(EXE) - -# -# Compile Doug's verif program that compares binary file regions -# -$(VERIFY): $(SRC)verify.c Makefile $(MK) - $(QUIET)$(TCC) $(TCCOPT) $(SRC)verify.c -o $(BIN)verify - -$(BIN)lechocr.exe: $(SRC)lechocr.c $(MK) -# $(QUIET)$(TCC) $(TCCOPT) $(SRC)lechocr.c -o $(BIN)lechocr - $(TCC) $(TCCOPT) $(SRC)lechocr.c -o lechocr.exe - $(COPY) lechocr.exe $(BIN) - -$(BIN)lecholf.exe: $(SRC)lecholf.c $(MK) -# $(QUIET)$(TCC) $(TCCFLG) $(SRC)lecholf.c -o $(BIN)lecholf - $(TCC) $(TCCOPT) $(SRC)lecholf.c -o lecholf.exe - $(COPY) lecholf.exe $(BIN) - -$(BIN)lechocrlf.exe: $(SRC)lechocrlf.c $(MK) -# $(QUIET)$(TCC) $(TCCOPT) $(SRC)lechocrlf.c -o $(BIN)lechocrlf - $(TCC) $(TCCOPT) $(SRC)lechocrlf.c -o lechocrlf.exe - $(COPY) lechocrlf.exe $(BIN) - -$(BIN)lecholfcr.exe: $(SRC)lecholfcr.c $(MK) -# $(QUIET)$(TCC) $(TCCFLG) $(SRC)lecholfcr.c -o $(BIN)lecholfcr - $(TCC) $(TCCOPT) $(SRC)lecholfcr.c -o lecholfcr.exe - $(COPY) lecholfcr.exe $(BIN) - -############################################################ - -# Builder specific utility rules - -dwginstall: - $(COPY) $(COMFILES) ~/Documents/devobox/cdrive - -############################################################ - -# -# Delete all dynamically generated files that don't need to be -# saved. -# -clean: - $(QUIET)$(DEL) $(DELFLG) *.hex *.ihx *.lst *.rel *.rst *.lnk *.lk - $(QUIET)$(DEL) $(DELFLG) *.sym *.map *.noi *.asm *.com *.ini *.bin - $(QUIET)$(DEL) $(DELFLG) obj$(DELIM)*.* bin$(DELIM)*.* com$(DELIM)*.* rom$(DELIM)*.* tmp$(DELIM)*.* map$(DELIM)*.* lst$(DELIM)*.* - -################## -# eof - Makefile # -################## diff --git a/doug/ref/JRC0521.ZIP b/doug/ref/JRC0521.ZIP deleted file mode 100755 index 55eb7806..00000000 Binary files a/doug/ref/JRC0521.ZIP and /dev/null differ diff --git a/doug/ref/bdosb01.asm b/doug/ref/bdosb01.asm deleted file mode 100755 index b5883d94..00000000 --- a/doug/ref/bdosb01.asm +++ /dev/null @@ -1,2587 +0,0 @@ - .title "Digital Research BDOS, Version 2.2" - .page 49 - -ENDFIL .EQU 1 ;FILL FULL BDOS LENGTH -; -IOBYTE: .EQU 3 ; I/O DEFINITION BYTE. -TDRIVE: .EQU 4 ; CURRENT DRIVE NAME AND USER NUMBER. -ENTRY: .EQU 5 ; ENTRY POINT FOR THE CP/M BDOS. -TFCB: .EQU 5CH ; DEFAULT FILE CONTROL BLOCK. -TBUFF: .EQU 80H ; I/O BUFFER AND COMMAND LINE STORAGE. -TBASE: .EQU 100H ; TRANSIANT PROGRAM STORAGE AREA. -; -; SET CONTROL CHARACTER .EQUATES. -; -CNTRLC: .EQU 3 ; CONTROL-C -CNTRLE: .EQU 05H ; CONTROL-E -BS: .EQU 08H ; BACKSPACE -TAB: .EQU 09H ; TAB -LF: .EQU 0AH ; LINE FEED -FF: .EQU 0CH ; FORM FEED -CR: .EQU 0DH ; CARRIAGE RETURN -CNTRLP: .EQU 10H ; CONTROL-P -CNTRLR: .EQU 12H ; CONTROL-R -CNTRLS: .EQU 13H ; CONTROL-S -CNTRLU: .EQU 15H ; CONTROL-U -CNTRLX: .EQU 18H ; CONTROL-X -CNTRLZ: .EQU 1AH ; CONTROL-Z (END-OF-FILE MARK) -DEL: .EQU 7FH ; RUBOUT - -; CPM ORIGIN CALCULATE - -NK .EQU 59 ;SYSTEM SIZE -BASE .EQU (NK*1024)-5000H -CCPO .EQU BASE+3400H ;CCP ORIGIN -BDOSO .EQU BASE+3C00H ;BDOS ORIGIN -BIOSO .EQU BASE+4A00H ;BIOS ORIGIN - - .ORG BDOSO - .DB 0,0,0,0,0,0 ;OLD SERIAL NUMBER -; -;************************************************************** -;* -;* B D O S E N T R Y -;* -;************************************************************** -; -FBASE: JP FBASE1 -; -; BDOS ERROR TABLE. -; -BADSCTR:.DW ERROR1 ; BAD SECTOR ON READ OR WRITE. -BADSLCT:.DW ERROR2 ; BAD DISK SELECT. -RODISK: .DW ERROR3 ; DISK IS READ ONLY. -ROFILE: .DW ERROR4 ; FILE IS READ ONLY. -; -; ENTRY INTO BDOS. (DE) OR (E) ARE THE PARAMETERS PASSED. THE -; FUNCTION NUMBER DESIRED IS IN REGISTER (C). -; E contains drive number if passing this -FBASE1: EX DE,HL ; SAVE THE (DE) PARAMETERS. - LD (PARAMS),HL - EX DE,HL - LD A,E ; AND SAVE REGISTER (E) IN PARTICULAR. - LD (EPARAM),A - LD HL,0 - LD (STATUS),HL ; CLEAR RETURN STATUS. - ADD HL,SP - LD (USRSTACK),HL ; SAVE USERS STACK POINTER. - LD SP,STKAREA ; AND SET OUR OWN. - XOR A ; CLEAR AUTO SELECT STORAGE SPACE. - LD (AUTOFLAG),A - LD (AUTO),A - LD HL,GOBACK ; SET RETURN ADDRESS. - PUSH HL - LD A,C ; GET FUNCTION NUMBER. - CP NFUNCTS ; VALID FUNCTION NUMBER? - RET NC - LD C,E ; KEEP SINGLE REGISTER FUNCTION HERE. - LD HL,FUNCTNS ; NOW LOOK THRU THE FUNCTION TABLE. - LD E,A - LD D,0 ; (DE)=FUNCTION NUMBER. - ADD HL,DE - ADD HL,DE ; (HL)=(START OF TABLE)+2*(FUNCTION NUMBER). - LD E,(HL) - INC HL - LD D,(HL) ; NOW (DE)=ADDRESS FOR THIS FUNCTION. - LD HL,(PARAMS) ; RETRIEVE PARAMETERS. - EX DE,HL ; NOW (DE) HAS THE ORIGINAL PARAMETERS. - JP (HL) ; EXECUTE DESIRED FUNCTION. -; -; BDOS FUNCTION JUMP TABLE. -; -NFUNCTS:.EQU 41 ; NUMBER OF FUNCTIONS IN FOLLOWIN TABLE. -; -FUNCTNS:.DW WBOOT,GETCON,OUTCON,GETRDR,PUNCH,LIST,DIRCIO,GETIOB - .DW SETIOB,PRTSTR,R.DBUFF,GETCSTS,GETVER,RSTDSK,SETDSK,OPENFIL - .DW CLOSEFIL,GETFST,GETNXT,DELFILE,READSEQ,WRTSEQ,FCREATE - .DW RENFILE,GETLOG,GETCRNT,PUTDMA,GETALOC,WRTPRTD,GETROV,SETATTR - .DW GETPARM,GETUSER,RDRANDOM,WTRANDOM,FILESIZE,SETRAN,LOGOFF,RTN - .DW RTN,WTSPECL -; -; BDOS ERROR MESSAGE SECTION. -; -ERROR1: LD HL,BADSEC ; BAD SECTOR MESSAGE. - CALL PRTERR ; PRINT IT AND GET A 1 CHAR RESPONCE. - CP CNTRLC ; RE-BOOT R.EQUEST (CONTROL-C)? - JP Z,0 ; YES. - RET ; NO, RETURN TO RETRY I/O FUNCTION. -; -ERROR2: LD HL,BADSEL ; BAD DRIVE SELECTED. - JP ERROR5 -; -ERROR3: LD HL,DISKRO ; DISK IS READ ONLY. - JP ERROR5 -; -ERROR4: LD HL,FILERO ; FILE IS READ ONLY. -; -ERROR5: CALL PRTERR - JP 0 ; ALWAYS REBOOT ON THESE ERRORS. -; -BDOSERR:.DB "BDOS ERR ON " -BDOSDRV:.DB " : $" -BADSEC: .DB "BAD SECTOR$" -BADSEL: .DB "SELECT$" -FILERO: .DB "FILE " -DISKRO: .DB "R/O$" -; -; PRINT BDOS ERROR MESSAGE. -; -PRTERR: PUSH HL ; SAVE SECOND MESSAGE POINTER. - CALL OUTCRLF ; SEND (CR)(LF). - LD A,(ACTIVE) ; GET ACTIVE DRIVE. - ADD A,'A' ; MAKE ASCII. - LD (BDOSDRV),A ; AND PUT IN MESSAGE. - LD BC,BDOSERR ; AND PRINT IT. - CALL PRTMESG - POP BC ; PRINT SECOND MESSAGE LINE NOW. - CALL PRTMESG -; -; GET AN INPUT CHARACTER. WE WILL CHECK OUR 1 CHARACTER -; BUFFER FIRST. THIS MAY BE SET BY THE CONSOLE STATUS ROUTINE. -; -GETCHAR:LD HL,CHARBUF ; CHECK CHARACTER BUFFER. - LD A,(HL) ; ANYTHING PRESENT ALREADY? - LD (HL),0 ; ...EITHER CASE CLEAR IT. - OR A - RET NZ ; YES, USE IT. - JP CONIN ; NOPE, GO GET A CHARACTER RESPONCE. -; -; INPUT AND ECHO A CHARACTER. -; -GETECHO:CALL GETCHAR ; INPUT A CHARACTER. - CALL CHKCHAR ; CARRIAGE CONTROL? - RET C ; NO, A REGULAR CONTROL CHAR SO DON'T ECHO. - PUSH AF ; OK, SAVE CHARACTER NOW. - LD C,A - CALL OUTCON ; AND ECHO IT. - POP AF ; GET CHARACTER AND RETURN. - RET -; -; CHECK CHARACTER IN (A). SET THE ZERO FLAG ON A CARRIAGE -; CONTROL CHARACTER AND THE CARRY FLAG ON ANY OTHER CONTROL -; CHARACTER. -; -CHKCHAR:CP CR ; CHECK FOR CARRIAGE RETURN, LINE FEED, BACKSPACE, - RET Z ; OR A TAB. - CP LF - RET Z - CP TAB - RET Z - CP BS - RET Z - CP ' ' ; OTHER CONTROL CHAR? SET CARRY FLAG. - RET -; -; CHECK THE CONSOLE DURING OUTPUT. HALT ON A CONTROL-S, THEN -; REBOOT ON A CONTROL-C. IF ANYTHING ELSE IS READY, CLEAR THE -; ZERO FLAG AND RETURN (THE CALLING ROUTINE MAY WANT TO DO -; SOMETHING). -; -CKCONSOL: - LD A,(CHARBUF) ; CHECK BUFFER. - OR A ; IF ANYTHING, JUST RETURN WITHOUT CHECKING. - JP NZ,CKCON2 - CALL CONST ; NOTHING IN BUFFER. CHECK CONSOLE. - AND 01H ; LOOK AT BIT 0. - RET Z ; RETURN IF NOTHING. - CALL CONIN ; OK, GET IT. - CP CNTRLS ; IF NOT CONTROL-S, RETURN WITH ZERO CLEARED. - JP NZ,CKCON1 - CALL CONIN ; HALT PROCESSING UNTIL ANOTHER CHAR - CP CNTRLC ; IS TYPED. CONTROL-C? - JP Z,0 ; YES, REBOOT NOW. - XOR A ; NO, JUST PRETEND NOTHING WAS EVER READY. - RET -CKCON1: LD (CHARBUF),A ; SAVE CHARACTER IN BUFFER FOR LATER PROCESSING. -CKCON2: LD A,1 ; SET (A) TO NON ZERO TO MEAN SOMETHING IS READY. - RET -; -; OUTPUT (C) TO THE SCREEN. IF THE PRINTER FLIP-FLOP FLAG -; IS SET, WE WILL SEND CHARACTER TO PRINTER ALSO. THE CONSOLE -; WILL BE CHECKED IN THE PROCESS. -; -OUTCHAR:LD A,(OUTFLAG) ; CHECK OUTPUT FLAG. - OR A ; ANYTHING AND WE WON'T GENERATE OUTPUT. - JP NZ,OUTCHR1 - PUSH BC - CALL CKCONSOL ; CHECK CONSOLE (WE DON'T CARE WHATS THERE). - POP BC - PUSH BC - CALL CONOUT ; OUTPUT (C) TO THE SCREEN. - POP BC - PUSH BC - LD A,(PRTFLAG) ; CHECK PRINTER FLIP-FLOP FLAG. - OR A - CALL NZ,LIST ; PRINT IT ALSO IF NON-ZERO. - POP BC -OUTCHR1:LD A,C ; UPDATE CURSORS POSITION. - LD HL,CURPOS - CP DEL ; RUBOUTS DON'T DO ANYTHING HERE. - RET Z - INC (HL) ; BUMP LINE POINTER. - CP ' ' ; AND RETURN IF A NORMAL CHARACTER. - RET NC - DEC (HL) ; RESTORE AND CHECK FOR THE START OF THE LINE. - LD A,(HL) - OR A - RET Z ; INGNORE CONTROL CHARACTERS AT THE START OF THE LINE. - LD A,C - CP BS ; IS IT A BACKSPACE? - JP NZ,OUTCHR2 - DEC (HL) ; YES, BACKUP POINTER. - RET -OUTCHR2:CP LF ; IS IT A LINE FEED? - RET NZ ; IGNORE ANYTHING ELSE. - LD (HL),0 ; RESET POINTER TO START OF LINE. - RET -; -; OUTPUT (A) TO THE SCREEN. IF IT IS A CONTROL CHARACTER -; (OTHER THAN CARRIAGE CONTROL), USE ^X FORMAT. -; -SHOWIT: LD A,C - CALL CHKCHAR ; CHECK CHARACTER. - JP NC,OUTCON ; NOT A CONTROL, USE NORMAL OUTPUT. - PUSH AF - LD C,'^' ; FOR A CONTROL CHARACTER, PRECEED IT WITH '^'. - CALL OUTCHAR - POP AF - OR '@' ; AND THEN USE THE LETTER .EQUIVELANT. - LD C,A -; -; FUNCTION TO OUTPUT (C) TO THE CONSOLE DEVICE AND EXPAND TABS -; IF NECESSARY. -; -OUTCON: LD A,C - CP TAB ; IS IT A TAB? - JP NZ,OUTCHAR ; USE REGULAR OUTPUT. -OUTCON1:LD C,' ' ; YES IT IS, USE SPACES INSTEAD. - CALL OUTCHAR - LD A,(CURPOS) ; GO UNTIL THE CURSOR IS AT A MULTIPLE OF 8 - - AND 07H ; POSITION. - JP NZ,OUTCON1 - RET -; -; ECHO A BACKSPACE CHARACTER. ERASE THE PREVOIUS CHARACTER -; ON THE SCREEN. -; -BACKUP: CALL BACKUP1 ; BACKUP THE SCREEN 1 PLACE. - LD C,' ' ; THEN BLANK THAT CHARACTER. - CALL CONOUT -BACKUP1:LD C,BS ; THEN BACK SPACE ONCE MORE. - JP CONOUT -; -; SIGNAL A DELETED LINE. PRINT A '#' AT THE END AND START -; OVER. -; -NEWLINE:LD C,'#' - CALL OUTCHAR ; PRINT THIS. - CALL OUTCRLF ; START NEW LINE. -NEWLN1: LD A,(CURPOS) ; MOVE THE CURSOR TO THE STARTING POSITION. - LD HL,STARTING - CP (HL) - RET NC ; THERE YET? - LD C,' ' - CALL OUTCHAR ; NOPE, KEEP GOING. - JP NEWLN1 -; -; OUTPUT A (CR) (LF) TO THE CONSOLE DEVICE (SCREEN). -; -OUTCRLF:LD C,CR - CALL OUTCHAR - LD C,LF - JP OUTCHAR -; -; PRINT MESSAGE POINTED TO BY (BC). IT WILL END WITH A '$'. -; -PRTMESG:LD A,(BC) ; CHECK FOR TERMINATING CHARACTER. - CP '$' - RET Z - INC BC - PUSH BC ; OTHERWISE, BUMP POINTER AND PRINT IT. - LD C,A - CALL OUTCON - POP BC - JP PRTMESG -; -; FUNCTION TO EXECUTE A BUFFERED READ. -; -R.DBUFF: LD A,(CURPOS) ; USE PRESENT LOCATION AS STARTING ONE. - LD (STARTING),A - LD HL,(PARAMS) ; GET THE MAXIMUM BUFFER SPACE. - LD C,(HL) - INC HL ; POINT TO FIRST AVAILABLE SPACE. - PUSH HL ; AND SAVE. - LD B,0 ; KEEP A CHARACTER COUNT. -R.DBUF1: PUSH BC - PUSH HL -R.DBUF2: CALL GETCHAR ; GET THE NEXT INPUT CHARACTER. - AND 7FH ; STRIP BIT 7. - POP HL ; RESET REGISTERS. - POP BC - CP CR ; EN OF THE LINE? - JP Z,R.DBUF17 - CP LF - JP Z,R.DBUF17 - CP BS ; HOW ABOUT A BACKSPACE? - JP NZ,R.DBUF3 - LD A,B ; YES, BUT IGNORE AT THE BEGINNING OF THE LINE. - OR A - JP Z,R.DBUF1 - DEC B ; OK, UPDATE COUNTER. - LD A,(CURPOS) ; IF WE BACKSPACE TO THE START OF THE LINE, - LD (OUTFLAG),A ; TREAT AS A CANCEL (CONTROL-X). - JP R.DBUF10 -R.DBUF3: CP DEL ; USER TYPED A RUBOUT? - JP NZ,R.DBUF4 - LD A,B ; IGNORE AT THE START OF THE LINE. - OR A - JP Z,R.DBUF1 - LD A,(HL) ; OK, ECHO THE PREVOIUS CHARACTER. - DEC B ; AND RESET POINTERS (COUNTERS). - DEC HL - JP R.DBUF15 -R.DBUF4: CP CNTRLE ; PHYSICAL END OF LINE? - JP NZ,R.DBUF5 - PUSH BC ; YES, DO IT. - PUSH HL - CALL OUTCRLF - XOR A ; AND UPDATE STARTING POSITION. - LD (STARTING),A - JP R.DBUF2 -R.DBUF5: CP CNTRLP ; CONTROL-P? - JP NZ,R.DBUF6 - PUSH HL ; YES, FLIP THE PRINT FLAG FILP-FLOP BYTE. - LD HL,PRTFLAG - LD A,1 ; PRTFLAG=1-PRTFLAG - SUB (HL) - LD (HL),A - POP HL - JP R.DBUF1 -R.DBUF6: CP CNTRLX ; CONTROL-X (CANCEL)? - JP NZ,R.DBUF8 - POP HL -R.DBUF7: LD A,(STARTING) ; YES, BACKUP THE CURSOR TO HERE. - LD HL,CURPOS - CP (HL) - JP NC,R.DBUFF ; DONE YET? - DEC (HL) ; NO, DECREMENT POINTER AND OUTPUT BACK UP ONE SPACE. - CALL BACKUP - JP R.DBUF7 -R.DBUF8: CP CNTRLU ; CNTROL-U (CANCEL LINE)? - JP NZ,R.DBUF9 - CALL NEWLINE ; START A NEW LINE. - POP HL - JP R.DBUFF -R.DBUF9: CP CNTRLR ; CONTROL-R? - JP NZ,R.DBUF14 -R.DBUF10:PUSH BC ; YES, START A NEW LINE AND RETYPE THE OLD ONE. - CALL NEWLINE - POP BC - POP HL - PUSH HL - PUSH BC -R.DBUF11:LD A,B ; DONE WHOLE LINE YET? - OR A - JP Z,R.DBUF12 - INC HL ; NOPE, GET NEXT CHARACTER. - LD C,(HL) - DEC B ; COUNT IT. - PUSH BC - PUSH HL - CALL SHOWIT ; AND DISPLAY IT. - POP HL - POP BC - JP R.DBUF11 -R.DBUF12:PUSH HL ; DONE WITH LINE. IF WE WERE DISPLAYING - LD A,(OUTFLAG) ; THEN UPDATE CURSOR POSITION. - OR A - JP Z,R.DBUF2 - LD HL,CURPOS ; BECAUSE THIS LINE IS SHORTER, WE MUST - SUB (HL) ; BACK UP THE CURSOR (NOT THE SCREEN HOWEVER) - LD (OUTFLAG),A ; SOME NUMBER OF POSITIONS. -R.DBUF13:CALL BACKUP ; NOTE THAT AS LONG AS (OUTFLAG) IS NON - LD HL,OUTFLAG ; ZERO, THE SCREEN WILL NOT BE CHANGED. - DEC (HL) - JP NZ,R.DBUF13 - JP R.DBUF2 ; NOW JUST GET THE NEXT CHARACTER. -; -; JUST A NORMAL CHARACTER, PUT THIS IN OUR BUFFER AND ECHO. -; -R.DBUF14:INC HL - LD (HL),A ; STORE CHARACTER. - INC B ; AND COUNT IT. -R.DBUF15:PUSH BC - PUSH HL - LD C,A ; ECHO IT NOW. - CALL SHOWIT - POP HL - POP BC - LD A,(HL) ; WAS IT AN ABORT R.EQUEST? - CP CNTRLC ; CONTROL-C ABORT? - LD A,B - JP NZ,R.DBUF16 - CP 1 ; ONLY IF AT START OF LINE. - JP Z,0 -R.DBUF16:CP C ; NOPE, HAVE WE FILLED THE BUFFER? - JP C,R.DBUF1 -R.DBUF17:POP HL ; YES END THE LINE AND RETURN. - LD (HL),B - LD C,CR - JP OUTCHAR ; OUTPUT (CR) AND RETURN. -; -; FUNCTION TO GET A CHARACTER FROM THE CONSOLE DEVICE. -; -GETCON: CALL GETECHO ; GET AND ECHO. - JP SETSTAT ; SAVE STATUS AND RETURN. -; -; FUNCTION TO GET A CHARACTER FROM THE TAPE READER DEVICE. -; -GETRDR: CALL READER ; GET A CHARACTER FROM READER, SET STATUS AND RETURN. - JP SETSTAT -; -; FUNCTION TO PERFORM DIRECT CONSOLE I/O. IF (C) CONTAINS (FF) -; THEN THIS IS AN INPUT R.EQUEST. IF (C) CONTAINS (FE) THEN -; THIS IS A STATUS R.EQUEST. OTHERWISE WE ARE TO OUTPUT (C). -; -DIRCIO: LD A,C ; TEST FOR (FF). - INC A - JP Z,DIRC1 - INC A ; TEST FOR (FE). - JP Z,CONST - JP CONOUT ; JUST OUTPUT (C). -DIRC1: CALL CONST ; THIS IS AN INPUT R.EQUEST. - OR A - JP Z,GOBACK1 ; NOT READY? JUST RETURN (DIRECTLY). - CALL CONIN ; YES, GET CHARACTER. - JP SETSTAT ; SET STATUS AND RETURN. -; -; FUNCTION TO RETURN THE I/O BYTE. -; -GETIOB: LD A,(IOBYTE) - JP SETSTAT -; -; FUNCTION TO SET THE I/O BYTE. -; -SETIOB: LD HL,IOBYTE - LD (HL),C - RET -; -; FUNCTION TO PRINT THE CHARACTER STRING POINTED TO BY (DE) -; ON THE CONSOLE DEVICE. THE STRING ENDS WITH A '$'. -; -PRTSTR: EX DE,HL - LD C,L - LD B,H ; NOW (BC) POINTS TO IT. - JP PRTMESG -; -; FUNCTION TO INTERIGATE THE CONSOLE DEVICE. -; -GETCSTS:CALL CKCONSOL -; -; GET HERE TO SET THE STATUS AND RETURN TO THE CLEANUP -; SECTION. THEN BACK TO THE USER. -; -SETSTAT:LD (STATUS),A -RTN: RET -; -; SET THE STATUS TO 1 (READ OR WRITE ERROR CODE). -; -IOERR1: LD A,1 - JP SETSTAT -; -OUTFLAG:.DB 0 ; OUTPUT FLAG (NON ZERO MEANS NO OUTPUT). -STARTING: - .DB 2 ; STARTING POSITION FOR CURSOR. -CURPOS: .DB 0 ; CURSOR POSITION (0=START OF LINE). -PRTFLAG:.DB 0 ; PRINTER FLAG (CONTROL-P TOGGLE). LIST IF NON ZERO. -CHARBUF:.DB 0 ; SINGLE INPUT CHARACTER BUFFER. -; -; STACK AREA FOR BDOS CALLS. -; -USRSTACK: - .DW 0 ; SAVE USERS STACK POINTER HERE. -; - .DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -STKAREA:.EQU $ ; END OF STACK AREA. -; -USERNO: .DB 0 ; CURRENT USER NUMBER. -ACTIVE: .DB 0 ; CURRENTLY ACTIVE DRIVE. -PARAMS: .DW 0 ; SAVE (DE) PARAMETERS HERE ON ENTRY. -STATUS: .DW 0 ; STATUS RETURNED FROM BDOS FUNCTION. -; -; SELECT ERROR OCCURED, JUMP TO ERROR ROUTINE. -; -SLCTERR:LD HL,BADSLCT -; -; JUMP TO (HL) INDIRECTLY. -; -JUMPHL: LD E,(HL) - INC HL - LD D,(HL) ; NOW (DE) CONTAIN THE DESIRED ADDRESS. - EX DE,HL - JP (HL) -; -; BLOCK MOVE. (DE) TO (HL), (C) BYTES TOTAL. -; -DE2HL: INC C ; IS COUNT DOWN TO ZERO? -DE2HL1: DEC C - RET Z ; YES, WE ARE DONE. - LD A,(DE) ; NO, MOVE ONE MORE BYTE. - LD (HL),A - INC DE - INC HL - JP DE2HL1 ; AND REPEAT. -; -; SELECT THE DESIRED DRIVE. -; -SELECT: LD A,(ACTIVE) ; GET ACTIVE DISK. - LD C,A - CALL SELDSK ; SELECT IT. - LD A,H ; VALID DRIVE? - OR L ; VALID DRIVE? - RET Z ; RETURN IF NOT. -; -; HERE, THE BIOS RETURNED THE ADDRESS OF THE PARAMETER BLOCK -; IN (HL). WE WILL EXTRACT THE NECESSARY POINTERS AND SAVE THEM. -; - LD E,(HL) ; YES, GET ADDRESS OF TRANSLATION TABLE INTO (DE). - INC HL - LD D,(HL) - INC HL - LD (SCRATCH1),HL ; SAVE POINTERS TO SCRATCH AREAS. - INC HL - INC HL - LD (SCRATCH2),HL ; DITTO. - INC HL - INC HL - LD (SCRATCH3),HL ; DITTO. - INC HL - INC HL - EX DE,HL ; NOW SAVE THE TRANSLATION TABLE ADDRESS. - LD (XLATE),HL - LD HL,DIRBUF ; PUT THE NEXT 8 BYTES HERE. - LD C,8 ; THEY CONSIST OF THE DIRECTORY BUFFER - CALL DE2HL ; POINTER, PARAMETER BLOCK POINTER, - LD HL,(DISKPB) ; CHECK AND ALLOCATION VECTORS. - EX DE,HL - LD HL,SECTORS ; MOVE PARAMETER BLOCK INTO OUR RAM. - LD C,15 ; IT IS 15 BYTES LONG. - CALL DE2HL - LD HL,(DSKSIZE) ; CHECK DISK SIZE. - LD A,H ; MORE THAN 256 BLOCKS ON THIS? - LD HL,BIGDISK - LD (HL),0FFH ; SET TO SAMLL. - OR A - JP Z,SELECT1 - LD (HL),0 ; WRONG, SET TO LARGE. -SELECT1:LD A,0FFH ; CLEAR THE ZERO FLAG. - OR A - RET -; -; ROUTINE TO HOME THE DISK TRACK HEAD AND CLEAR POINTERS. -; -HOMEDRV:CALL HOME ; HOME THE HEAD. - XOR A - LD HL,(SCRATCH2) ; SET OUR TRACK POINTER ALSO. - LD (HL),A - INC HL - LD (HL),A - LD HL,(SCRATCH3) ; AND OUR SECTOR POINTER. - LD (HL),A - INC HL - LD (HL),A - RET -; -; DO THE ACTUAL DISK READ AND CHECK THE ERROR RETURN STATUS. -; -DOREAD: CALL READ - JP IORET -; -; DO THE ACTUAL DISK WRITE AND HANDLE ANY BIOS ERROR. -; -DOWRITE:CALL WRITE -IORET: OR A - RET Z ; RETURN UNLESS AN ERROR OCCURED. - LD HL,BADSCTR ; BAD READ/WRITE ON THIS SECTOR. - JP JUMPHL -; -; ROUTINE TO SELECT THE TRACK AND SECTOR THAT THE DESIRED -; BLOCK NUMBER FALLS IN. -; -TRKSEC: LD HL,(FILEPOS) ; GET POSITION OF LAST ACCESSED FILE - LD C,2 ; IN DIRECTORY AND COMPUTE SECTOR #. - CALL SHIFTR ; SECTOR #=FILE-POSITION/4. - LD (BLKNMBR),HL ; SAVE THIS AS THE BLOCK NUMBER OF INTEREST. - LD (CKSUMTBL),HL ; WHAT'S IT DOING HERE TOO? -; -; IF THE SECTOR NUMBER HAS ALREADY BEEN SET (BLKNMBR), ENTER -; AT THIS POINT. -; -TRKSEC1:LD HL,BLKNMBR - LD C,(HL) ; MOVE SECTOR NUMBER INTO (BC). - INC HL - LD B,(HL) - LD HL,(SCRATCH3) ; GET CURRENT SECTOR NUMBER AND - LD E,(HL) ; MOVE THIS INTO (DE). - INC HL - LD D,(HL) - LD HL,(SCRATCH2) ; GET CURRENT TRACK NUMBER. - LD A,(HL) ; AND THIS INTO (HL). - INC HL - LD H,(HL) - LD L,A -TRKSEC2:LD A,C ; IS DESIRED SECTOR BEFORE CURRENT ONE? - SUB E - LD A,B - SBC A,D - JP NC,TRKSEC3 - PUSH HL ; YES, DECREMENT SECTORS BY ONE TRACK. - LD HL,(SECTORS) ; GET SECTORS PER TRACK. - LD A,E - SUB L - LD E,A - LD A,D - SBC A,H - LD D,A ; NOW WE HAVE BACKED UP ONE FULL TRACK. - POP HL - DEC HL ; ADJUST TRACK COUNTER. - JP TRKSEC2 -TRKSEC3:PUSH HL ; DESIRED SECTOR IS AFTER CURRENT ONE. - LD HL,(SECTORS) ; GET SECTORS PER TRACK. - ADD HL,DE ; BUMP SECTOR POINTER TO NEXT TRACK. - JP C,TRKSEC4 - LD A,C ; IS DESIRED SECTOR NOW BEFORE CURRENT ONE? - SUB L - LD A,B - SBC A,H - JP C,TRKSEC4 - EX DE,HL ; NOT YES, INCREMENT TRACK COUNTER - POP HL ; AND CONTINUE UNTIL IT IS. - INC HL - JP TRKSEC3 -; -; HERE WE HAVE DETERMINED THE TRACK NUMBER THAT CONTAINS THE -; DESIRED SECTOR. -; -TRKSEC4:POP HL ; GET TRACK NUMBER (HL). - PUSH BC - PUSH DE - PUSH HL - EX DE,HL - LD HL,(OFFSET) ; ADJUST FOR FIRST TRACK OFFSET. - ADD HL,DE - LD B,H - LD C,L - CALL SETTRK ; SELECT THIS TRACK. - POP DE ; RESET CURRENT TRACK POINTER. - LD HL,(SCRATCH2) - LD (HL),E - INC HL - LD (HL),D - POP DE - LD HL,(SCRATCH3) ; RESET THE FIRST SECTOR ON THIS TRACK. - LD (HL),E - INC HL - LD (HL),D - POP BC - LD A,C ; NOW SUBTRACT THE DESIRED ONE. - SUB E ; TO MAKE IT RELATIVE (1-# SECTORS/TRACK). - LD C,A - LD A,B - SBC A,D - LD B,A - LD HL,(XLATE) ; TRANSLATE THIS SECTOR ACCORDING TO THIS TABLE. - EX DE,HL - CALL SECTRN ; LET THE BIOS TRANSLATE IT. - LD C,L - LD B,H - JP SETSEC ; AND SELECT IT. -; -; COMPUTE BLOCK NUMBER FROM RECORD NUMBER (SAVNREC) AND -; EXTENT NUMBER (SAVEXT). -; -GETBLOCK: - LD HL,BLKSHFT ; GET LOGICAL TO PHYSICAL CONVERSION. - LD C,(HL) ; NOTE THAT THIS IS BASE 2 LOG OF RATIO. - LD A,(SAVNREC) ; GET RECORD NUMBER. -GETBLK1:OR A ; COMPUTE (A)=(A)/2^BLKSHFT. - RRA - DEC C - JP NZ,GETBLK1 - LD B,A ; SAVE RESULT IN (B). - LD A,8 - SUB (HL) - LD C,A ; COMPUTE (C)=8-BLKSHFT. - LD A,(SAVEXT) -GETBLK2:DEC C ; COMPUTE (A)=SAVEXT*2^(8-BLKSHFT). - JP Z,GETBLK3 - OR A - RLA - JP GETBLK2 -GETBLK3:ADD A,B - RET -; -; ROUTINE TO EXTRACT THE (BC) BLOCK BYTE FROM THE FCB POINTED -; TO BY (PARAMS). IF THIS IS A BIG-DISK, THEN THESE ARE 16 BIT -; BLOCK NUMBERS, ELSE THEY ARE 8 BIT NUMBERS. -; NUMBER IS RETURNED IN (HL). -; -EXTBLK: LD HL,(PARAMS) ; GET FCB ADDRESS. - LD DE,16 ; BLOCK NUMBERS START 16 BYTES INTO FCB. - ADD HL,DE - ADD HL,BC - LD A,(BIGDISK) ; ARE WE USING A BIG-DISK? - OR A - JP Z,EXTBLK1 - LD L,(HL) ; NO, EXTRACT AN 8 BIT NUMBER FROM THE FCB. - LD H,0 - RET -EXTBLK1:ADD HL,BC ; YES, EXTRACT A 16 BIT NUMBER. - LD E,(HL) - INC HL - LD D,(HL) - EX DE,HL ; RETURN IN (HL). - RET -; -; COMPUTE BLOCK NUMBER. -; -COMBLK: CALL GETBLOCK - LD C,A - LD B,0 - CALL EXTBLK - LD (BLKNMBR),HL - RET -; -; CHECK FOR A ZERO BLOCK NUMBER (UNUSED). -; -CHKBLK: LD HL,(BLKNMBR) - LD A,L ; IS IT ZERO? - OR H - RET -; -; ADJUST PHYSICAL BLOCK (BLKNMBR) AND CONVERT TO LOGICAL -; SECTOR (LOGSECT). THIS IS THE STARTING SECTOR OF THIS BLOCK. -; THE ACTUAL SECTOR OF INTEREST IS THEN ADDED TO THIS AND THE -; RESULTING SECTOR NUMBER IS STORED BACK IN (BLKNMBR). THIS -; WILL STILL HAVE TO BE ADJUSTED FOR THE TRACK NUMBER. -; -LOGICAL:LD A,(BLKSHFT) ; GET LOG2(PHYSICAL/LOGICAL SECTORS). - LD HL,(BLKNMBR) ; GET PHYSICAL SECTOR DESIRED. -LOGICL1:ADD HL,HL ; COMPUTE LOGICAL SECTOR NUMBER. - DEC A ; NOTE LOGICAL SECTORS ARE 128 BYTES LONG. - JP NZ,LOGICL1 - LD (LOGSECT),HL ; SAVE LOGICAL SECTOR. - LD A,(BLKMASK) ; GET BLOCK MASK. - LD C,A - LD A,(SAVNREC) ; GET NEXT SECTOR TO ACCESS. - AND C ; EXTRACT THE RELATIVE POSITION WITHIN PHYSICAL BLOCK. - OR L ; AND ADD IT TOO LOGICAL SECTOR. - LD L,A - LD (BLKNMBR),HL ; AND STORE. - RET -; -; SET (HL) TO POINT TO EXTENT BYTE IN FCB. -; -SETEXT: LD HL,(PARAMS) - LD DE,12 ; IT IS THE TWELTH BYTE. - ADD HL,DE - RET -; -; SET (HL) TO POINT TO RECORD COUNT BYTE IN FCB AND (DE) TO -; NEXT RECORD NUMBER BYTE. -; -SETHLDE:LD HL,(PARAMS) - LD DE,15 ; RECORD COUNT BYTE (#15). - ADD HL,DE - EX DE,HL - LD HL,17 ; NEXT RECORD NUMBER (#32). - ADD HL,DE - RET -; -; SAVE CURRENT FILE DATA FROM FCB. -; -STRDATA:CALL SETHLDE - LD A,(HL) ; GET AND STORE RECORD COUNT BYTE. - LD (SAVNREC),A - EX DE,HL - LD A,(HL) ; GET AND STORE NEXT RECORD NUMBER BYTE. - LD (SAVNXT),A - CALL SETEXT ; POINT TO EXTENT BYTE. - LD A,(EXTMASK) ; GET EXTENT MASK. - AND (HL) - LD (SAVEXT),A ; AND SAVE EXTENT HERE. - RET -; -; SET THE NEXT RECORD TO ACCESS. IF (MODE) IS SET TO 2, THEN -; THE LAST RECORD BYTE (SAVNREC) HAS THE CORRECT NUMBER TO ACCESS. -; FOR S.EQUENTIAL ACCESS, (MODE) WILL BE .EQUAL TO 1. -; -SETNREC:CALL SETHLDE - LD A,(MODE) ; GET S.EQUENTIAL FLAG (=1). - CP 2 ; A 2 INDICATES THAT NO ADDER IS NEEDED. - JP NZ,STNREC1 - XOR A ; CLEAR ADDER (RANDOM ACCESS?). -STNREC1:LD C,A - LD A,(SAVNREC) ; GET LAST RECORD NUMBER. - ADD A,C ; INCREMENT RECORD COUNT. - LD (HL),A ; AND SET FCB'S NEXT RECORD BYTE. - EX DE,HL - LD A,(SAVNXT) ; GET NEXT RECORD BYTE FROM STORAGE. - LD (HL),A ; AND PUT THIS INTO FCB AS NUMBER OF RECORDS USED. - RET -; -; SHIFT (HL) RIGHT (C) BITS. -; -SHIFTR: INC C -SHIFTR1:DEC C - RET Z - LD A,H - OR A - RRA - LD H,A - LD A,L - RRA - LD L,A - JP SHIFTR1 -; -; COMPUTE THE CHECK-SUM FOR THE DIRECTORY BUFFER. RETURN -; INTEGER SUM IN (A). -; -CHECKSUM: - LD C,128 ; LENGTH OF BUFFER. - LD HL,(DIRBUF) ; GET ITS LOCATION. - XOR A ; CLEAR SUMMATION BYTE. -CHKSUM1:ADD A,(HL) ; AND COMPUTE SUM IGNORING CARRIES. - INC HL - DEC C - JP NZ,CHKSUM1 - RET -; -; SHIFT (HL) LEFT (C) BITS. -; -SHIFTL: INC C -SHIFTL1:DEC C - RET Z - ADD HL,HL ; SHIFT LEFT 1 BIT. - JP SHIFTL1 -; -; ROUTINE TO SET A BIT IN A 16 BIT VALUE CONTAINED IN (BC). -; THE BIT SET DEPENDS ON THE CURRENT DRIVE SELECTION. -; -SETBIT: PUSH BC ; SAVE 16 BIT WORD. - LD A,(ACTIVE) ; GET ACTIVE DRIVE. - LD C,A - LD HL,1 - CALL SHIFTL ; SHIFT BIT 0 INTO PLACE. - POP BC ; NOW 'OR' THIS WITH THE ORIGINAL WORD. - LD A,C - OR L - LD L,A ; LOW BYTE DONE, DO HIGH BYTE. - LD A,B - OR H - LD H,A - RET -; -; EXTRACT THE WRITE PROTECT STATUS BIT FOR THE CURRENT DRIVE. -; THE RESULT IS RETURNED IN (A), BIT 0. -; -GETWPRT:LD HL,(WRTPRT) ; GET STATUS BYTES. - LD A,(ACTIVE) ; WHICH DRIVE IS CURRENT? - LD C,A - CALL SHIFTR ; SHIFT STATUS SUCH THAT BIT 0 IS THE - LD A,L ; ONE OF INTEREST FOR THIS DRIVE. - AND 01H ; AND ISOLATE IT. - RET -; -; FUNCTION TO WRITE PROTECT THE CURRENT DISK. -; -WRTPRTD:LD HL,WRTPRT ; POINT TO STATUS WORD. - LD C,(HL) ; SET (BC) .EQUAL TO THE STATUS. - INC HL - LD B,(HL) - CALL SETBIT ; AND SET THIS BIT ACCORDING TO CURRENT DRIVE. - LD (WRTPRT),HL ; THEN SAVE. - LD HL,(DIRSIZE) ; NOW SAVE DIRECTORY SIZE LIMIT. - INC HL ; REMEMBER THE LAST ONE. - EX DE,HL - LD HL,(SCRATCH1) ; AND STORE IT HERE. - LD (HL),E ; PUT LOW BYTE. - INC HL - LD (HL),D ; THEN HIGH BYTE. - RET -; -; CHECK FOR A READ ONLY FILE. -; -CHKROFL:CALL FCB2HL ; SET (HL) TO FILE ENTRY IN DIRECTORY BUFFER. -CKROF1: LD DE,9 ; LOOK AT BIT 7 OF THE NINTH BYTE. - ADD HL,DE - LD A,(HL) - RLA - RET NC ; RETURN IF OK. - LD HL,ROFILE ; ELSE, PRINT ERROR MESSAGE AND TERMINATE. - JP JUMPHL -; -; CHECK THE WRITE PROTECT STATUS OF THE ACTIVE DISK. -; -CHKWPRT:CALL GETWPRT - RET Z ; RETURN IF OK. - LD HL,RODISK ; ELSE PRINT MESSAGE AND TERMINATE. - JP JUMPHL -; -; ROUTINE TO SET (HL) POINTING TO THE PROPER ENTRY IN THE -; DIRECTORY BUFFER. -; -FCB2HL: LD HL,(DIRBUF) ; GET ADDRESS OF BUFFER. - LD A,(FCBPOS) ; RELATIVE POSITION OF FILE. -; -; ROUTINE TO ADD (A) TO (HL). -; -ADDA2HL:ADD A,L - LD L,A - RET NC - INC H ; TAKE CARE OF ANY CARRY. - RET -; -; ROUTINE TO GET THE 'S2' BYTE FROM THE FCB SUPPLIED IN -; THE INITIAL PARAMETER SPECIFICATION. -; -GETS2: LD HL,(PARAMS) ; GET ADDRESS OF FCB. - LD DE,14 ; RELATIVE POSITION OF 'S2'. - ADD HL,DE - LD A,(HL) ; EXTRACT THIS BYTE. - RET -; -; CLEAR THE 'S2' BYTE IN THE FCB. -; -CLEARS2:CALL GETS2 ; THIS SETS (HL) POINTING TO IT. - LD (HL),0 ; NOW CLEAR IT. - RET -; -; SET BIT 7 IN THE 'S2' BYTE OF THE FCB. -; -SETS2B7:CALL GETS2 ; GET THE BYTE. - OR 80H ; AND SET BIT 7. - LD (HL),A ; THEN STORE. - RET -; -; COMPARE (FILEPOS) WITH (SCRATCH1) AND SET FLAGS BASED ON -; THE DIFFERENCE. THIS CHECKS TO SEE IF THERE ARE MORE FILE -; NAMES IN THE DIRECTORY. WE ARE AT (FILEPOS) AND THERE ARE -; (SCRATCH1) OF THEM TO CHECK. -; -MOREFLS:LD HL,(FILEPOS) ; WE ARE HERE. - EX DE,HL - LD HL,(SCRATCH1) ; AND DON'T GO PAST HERE. - LD A,E ; COMPUTE DIFFERENCE BUT DON'T KEEP. - SUB (HL) - INC HL - LD A,D - SBC A,(HL) ; SET CARRY IF NO MORE NAMES. - RET -; -; CALL THIS ROUTINE TO PREVENT (SCRATCH1) FROM BEING GREATER -; THAN (FILEPOS). -; -CHKNMBR:CALL MOREFLS ; SCRATCH1 TOO BIG? - RET C - INC DE ; YES, RESET IT TO (FILEPOS). - LD (HL),D - DEC HL - LD (HL),E - RET -; -; COMPUTE (HL)=(DE)-(HL) -; -SUBHL: LD A,E ; COMPUTE DIFFERENCE. - SUB L - LD L,A ; STORE LOW BYTE. - LD A,D - SBC A,H - LD H,A ; AND THEN HIGH BYTE. - RET -; -; SET THE DIRECTORY CHECKSUM BYTE. -; -SETDIR: LD C,0FFH -; -; ROUTINE TO SET OR COMPARE THE DIRECTORY CHECKSUM BYTE. IF -; (C)=0FFH, THEN THIS WILL SET THE CHECKSUM BYTE. ELSE THE BYTE -; WILL BE CHECKED. IF THE CHECK FAILS (THE DISK HAS BEEN CHANGED), -; THEN THIS DISK WILL BE WRITE PROTECTED. -; -CHECKDIR: - LD HL,(CKSUMTBL) - EX DE,HL - LD HL,(ALLOC1) - CALL SUBHL - RET NC ; OK IF (CKSUMTBL) > (ALLOC1), SO RETURN. - PUSH BC - CALL CHECKSUM ; ELSE COMPUTE CHECKSUM. - LD HL,(CHKVECT) ; GET ADDRESS OF CHECKSUM TABLE. - EX DE,HL - LD HL,(CKSUMTBL) - ADD HL,DE ; SET (HL) TO POINT TO BYTE FOR THIS DRIVE. - POP BC - INC C ; SET OR CHECK ? - JP Z,CHKDIR1 - CP (HL) ; CHECK THEM. - RET Z ; RETURN IF THEY ARE THE SAME. - CALL MOREFLS ; NOT THE SAME, DO WE CARE? - RET NC - CALL WRTPRTD ; YES, MARK THIS AS WRITE PROTECTED. - RET -CHKDIR1:LD (HL),A ; JUST SET THE BYTE. - RET -; -; DO A WRITE TO THE DIRECTORY OF THE CURRENT DISK. -; -DIRWRITE: - CALL SETDIR ; SET CHECKSUM BYTE. - CALL DIRDMA ; SET DIRECTORY DMA ADDRESS. - LD C,1 ; TELL THE BIOS TO ACTUALLY WRITE. - CALL DOWRITE ; THEN DO THE WRITE. - JP DEFDMA -; -; READ FROM THE DIRECTORY. -; -DIRREAD:CALL DIRDMA ; SET THE DIRECTORY DMA ADDRESS. - CALL DOREAD ; AND READ IT. -; -; ROUTINE TO SET THE DMA ADDRESS TO THE USERS CHOICE. -; -DEFDMA: LD HL,USERDMA ; RESET THE DEFAULT DMA ADDRESS AND RETURN. - JP DIRDMA1 -; -; ROUTINE TO SET THE DMA ADDRESS FOR DIRECTORY WORK. -; -DIRDMA: LD HL,DIRBUF -; -; SET THE DMA ADDRESS. ON ENTRY, (HL) POINTS TO -; WORD CONTAINING THE DESIRED DMA ADDRESS. -; -DIRDMA1:LD C,(HL) - INC HL - LD B,(HL) ; SETUP (BC) AND GO TO THE BIOS TO SET IT. - JP SETDMA -; -; MOVE THE DIRECTORY BUFFER INTO USER'S DMA SPACE. -; -MOVEDIR:LD HL,(DIRBUF) ; BUFFER IS LOCATED HERE, AND - EX DE,HL - LD HL,(USERDMA) ; PUT IT HERE. - LD C,128 ; THIS IS ITS LENGTH. - JP DE2HL ; MOVE IT NOW AND RETURN. -; -; CHECK (FILEPOS) AND SET THE ZERO FLAG IF IT .EQUALS 0FFFFH. -; -CKFILPOS: - LD HL,FILEPOS - LD A,(HL) - INC HL - CP (HL) ; ARE BOTH BYTES THE SAME? - RET NZ - INC A ; YES, BUT ARE THEY EACH 0FFH? - RET -; -; SET LOCATION (FILEPOS) TO 0FFFFH. -; -STFILPOS: - LD HL,0FFFFH - LD (FILEPOS),HL - RET -; -; MOVE ON TO THE NEXT FILE POSITION WITHIN THE CURRENT -; DIRECTORY BUFFER. IF NO MORE EXIST, SET POINTER TO 0FFFFH -; AND THE CALLING ROUTINE WILL CHECK FOR THIS. ENTER WITH (C) -; .EQUAL TO 0FFH TO CAUSE THE CHECKSUM BYTE TO BE SET, ELSE WE -; WILL CHECK THIS DISK AND SET WRITE PROTECT IF CHECKSUMS ARE -; NOT THE SAME (APPLIES ONLY IF ANOTHER DIRECTORY SECTOR MUST -; BE READ). -; -NXENTRY:LD HL,(DIRSIZE) ; GET DIRECTORY ENTRY SIZE LIMIT. - EX DE,HL - LD HL,(FILEPOS) ; GET CURRENT COUNT. - INC HL ; GO ON TO THE NEXT ONE. - LD (FILEPOS),HL - CALL SUBHL ; (HL)=(DIRSIZE)-(FILEPOS) - JP NC,NXENT1 ; IS THERE MORE ROOM LEFT? - JP STFILPOS ; NO. SET THIS FLAG AND RETURN. -NXENT1: LD A,(FILEPOS) ; GET FILE POSITION WITHIN DIRECTORY. - AND 03H ; ONLY LOOK WITHIN THIS SECTOR (ONLY 4 ENTRIES FIT). - LD B,5 ; CONVERT TO RELATIVE POSITION (32 BYTES EACH). -NXENT2: ADD A,A ; NOTE THAT THIS IS NOT EFFICIENT CODE. - DEC B ; 5 'ADD A'S WOULD BE BETTER. - JP NZ,NXENT2 - LD (FCBPOS),A ; SAVE IT AS POSITION OF FCB. - OR A - RET NZ ; RETURN IF WE ARE WITHIN BUFFER. - PUSH BC - CALL TRKSEC ; WE NEED THE NEXT DIRECTORY SECTOR. - CALL DIRREAD - POP BC - JP CHECKDIR -; -; ROUTINE TO TO GET A BIT FROM THE DISK SPACE ALLOCATION -; MAP. IT IS RETURNED IN (A), BIT POSITION 0. ON ENTRY TO HERE, -; SET (BC) TO THE BLOCK NUMBER ON THE DISK TO CHECK. -; ON RETURN, (D) WILL CONTAIN THE ORIGINAL BIT POSITION FOR -; THIS BLOCK NUMBER AND (HL) WILL POINT TO THE ADDRESS FOR IT. -; -CKBITMAP: - LD A,C ; DETERMINE BIT NUMBER OF INTEREST. - AND 07H ; COMPUTE (D)=(E)=(C AND 7)+1. - INC A - LD E,A ; SAVE PARTICULAR BIT NUMBER. - LD D,A -; -; COMPUTE (BC)=(BC)/8. -; - LD A,C - RRCA ; NOW SHIFT RIGHT 3 BITS. - RRCA - RRCA - AND 1FH ; AND CLEAR BITS 7,6,5. - LD C,A - LD A,B - ADD A,A ; NOW SHIFT (B) INTO BITS 7,6,5. - ADD A,A - ADD A,A - ADD A,A - ADD A,A - OR C ; AND ADD IN (C). - LD C,A ; OK, (C) HA BEEN COMPLETED. - LD A,B ; IS THERE A BETTER WAY OF DOING THIS? - RRCA - RRCA - RRCA - AND 1FH - LD B,A ; AND NOW (B) IS COMPLETED. -; -; USE THIS AS AN OFFSET INTO THE DISK SPACE ALLOCATION -; TABLE. -; - LD HL,(ALOCVECT) - ADD HL,BC - LD A,(HL) ; NOW GET CORRECT BYTE. -CKBMAP1:RLCA ; GET CORRECT BIT INTO POSITION 0. - DEC E - JP NZ,CKBMAP1 - RET -; -; SET OR CLEAR THE BIT MAP SUCH THAT BLOCK NUMBER (BC) WILL BE MARKED -; AS USED. ON ENTRY, IF (E)=0 THEN THIS BIT WILL BE CLEARED, IF IT .EQUALS -; 1 THEN IT WILL BE SET (DON'T USE ANYOTHER VALUES). -; -STBITMAP: - PUSH DE - CALL CKBITMAP ; GET THE BYTE OF INTEREST. - AND 0FEH ; CLEAR THE AFFECTED BIT. - POP BC - OR C ; AND NOW SET IT ACORDING TO (C). -; -; ENTRY TO RESTORE THE ORIGINAL BIT POSITION AND THEN STORE -; IN TABLE. (A) CONTAINS THE VALUE, (D) CONTAINS THE BIT -; POSITION (1-8), AND (HL) POINTS TO THE ADDRESS WITHIN THE -; SPACE ALLOCATION TABLE FOR THIS BYTE. -; -STBMAP1:RRCA ; RESTORE ORIGINAL BIT POSITION. - DEC D - JP NZ,STBMAP1 - LD (HL),A ; AND STOR BYTE IN TABLE. - RET -; -; SET/CLEAR SPACE USED BITS IN ALLOCATION MAP FOR THIS FILE. -; ON ENTRY, (C)=1 TO SET THE MAP AND (C)=0 TO CLEAR IT. -; -SETFILE:CALL FCB2HL ; GET ADDRESS OF FCB - LD DE,16 - ADD HL,DE ; GET TO BLOCK NUMBER BYTES. - PUSH BC - LD C,17 ; CHECK ALL 17 BYTES (MAX) OF TABLE. -SETFL1: POP DE - DEC C ; DONE ALL BYTES YET? - RET Z - PUSH DE - LD A,(BIGDISK) ; CHECK DISK SIZE FOR 16 BIT BLOCK NUMBERS. - OR A - JP Z,SETFL2 - PUSH BC ; ONLY 8 BIT NUMBERS. SET (BC) TO THIS ONE. - PUSH HL - LD C,(HL) ; GET LOW BYTE FROM TABLE, ALWAYS - LD B,0 ; SET HIGH BYTE TO ZERO. - JP SETFL3 -SETFL2: DEC C ; FOR 16 BIT BLOCK NUMBERS, ADJUST COUNTER. - PUSH BC - LD C,(HL) ; NOW GET BOTH THE LOW AND HIGH BYTES. - INC HL - LD B,(HL) - PUSH HL -SETFL3: LD A,C ; BLOCK USED? - OR B - JP Z,SETFL4 - LD HL,(DSKSIZE) ; IS THIS BLOCK NUMBER WITHIN THE - LD A,L ; SPACE ON THE DISK? - SUB C - LD A,H - SBC A,B - CALL NC,STBITMAP ; YES, SET THE PROPER BIT. -SETFL4: POP HL ; POINT TO NEXT BLOCK NUMBER IN FCB. - INC HL - POP BC - JP SETFL1 -; -; CONSTRUCT THE SPACE USED ALLOCATION BIT MAP FOR THE ACTIVE -; DRIVE. IF A FILE NAME STARTS WITH '$' AND IT IS UNDER THE -; CURRENT USER NUMBER, THEN (STATUS) IS SET TO MINUS 1. OTHERWISE -; IT IS NOT SET AT ALL. -; -BITMAP: LD HL,(DSKSIZE) ; COMPUTE SIZE OF ALLOCATION TABLE. - LD C,3 - CALL SHIFTR ; (HL)=(HL)/8. - INC HL ; AT LEASE 1 BYTE. - LD B,H - LD C,L ; SET (BC) TO THE ALLOCATION TABLE LENGTH. -; -; INITIALIZE THE BITMAP FOR THIS DRIVE. RIGHT NOW, THE FIRST -; TWO BYTES ARE SPECIFIED BY THE DISK PARAMETER BLOCK. HOWEVER -; A PATCH COULD BE ENTERED HERE IF IT WERE NECESSARY TO SETUP -; THIS TABLE IN A SPECIAL MANNOR. FOR EXAMPLE, THE BIOS COULD -; DETERMINE LOCATIONS OF 'BAD BLOCKS' AND SET THEM AS ALREADY -; 'USED' IN THE MAP. -; - LD HL,(ALOCVECT) ; NOW ZERO OUT THE TABLE NOW. -BITMAP1:LD (HL),0 - INC HL - DEC BC - LD A,B - OR C - JP NZ,BITMAP1 - LD HL,(ALLOC0) ; GET INITIAL SPACE USED BY DIRECTORY. - EX DE,HL - LD HL,(ALOCVECT) ; AND PUT THIS INTO MAP. - LD (HL),E - INC HL - LD (HL),D -; -; END OF INITIALIZATION PORTION. -; - CALL HOMEDRV ; NOW HOME THE DRIVE. - LD HL,(SCRATCH1) - LD (HL),3 ; FORCE NEXT DIRECTORY R.EQUEST TO READ - INC HL ; IN A SECTOR. - LD (HL),0 - CALL STFILPOS ; CLEAR INITIAL FILE POSITION ALSO. -BITMAP2:LD C,0FFH ; READ NEXT FILE NAME IN DIRECTORY - CALL NXENTRY ; AND SET CHECKSUM BYTE. - CALL CKFILPOS ; IS THERE ANOTHER FILE? - RET Z - CALL FCB2HL ; YES, GET ITS ADDRESS. - LD A,0E5H - CP (HL) ; EMPTY FILE ENTRY? - JP Z,BITMAP2 - LD A,(USERNO) ; NO, CORRECT USER NUMBER? - CP (HL) - JP NZ,BITMAP3 - INC HL - LD A,(HL) ; YES, DOES NAME START WITH A '$'? - SUB '$' - JP NZ,BITMAP3 - DEC A ; YES, SET ATATUS TO MINUS ONE. - LD (STATUS),A -BITMAP3:LD C,1 ; NOW SET THIS FILE'S SPACE AS USED IN BIT MAP. - CALL SETFILE - CALL CHKNMBR ; KEEP (SCRATCH1) IN BOUNDS. - JP BITMAP2 -; -; SET THE STATUS (STATUS) AND RETURN. -; -STSTATUS: - LD A,(FNDSTAT) - JP SETSTAT -; -; CHECK EXTENTS IN (A) AND (C). SET THE ZERO FLAG IF THEY -; ARE THE SAME. THE NUMBER OF 16K CHUNKS OF DISK SPACE THAT -; THE DIRECTORY EXTENT COVERS IS EXPRESSAD IS (EXTMASK+1). -; NO REGISTERS ARE MODIFIED. -; -SAMEXT: PUSH BC - PUSH AF - LD A,(EXTMASK) ; GET EXTENT MASK AND USE IT TO - CPL ; TO COMPARE BOTH EXTENT NUMBERS. - LD B,A ; SAVE RESULTING MASK HERE. - LD A,C ; MASK FIRST EXTENT AND SAVE IN (C). - AND B - LD C,A - POP AF ; NOW MASK SECOND EXTENT AND COMPARE - AND B ; WITH THE FIRST ONE. - SUB C - AND 1FH ; (* ONLY CHECK BUTS 0-4 *) - POP BC ; THE ZERO FLAG IS SET IF THEY ARE THE SAME. - RET ; RESTORE (BC) AND RETURN. -; -; SEARCH FOR THE FIRST OCCURENCE OF A FILE NAME. ON ENTRY, -; REGISTER (C) SHOULD CONTAIN THE NUMBER OF BYTES OF THE FCB -; THAT MUST MATCH. -; -FINDFST:LD A,0FFH - LD (FNDSTAT),A - LD HL,COUNTER ; SAVE CHARACTER COUNT. - LD (HL),C - LD HL,(PARAMS) ; GET FILENAME TO MATCH. - LD (SAVEFCB),HL ; AND SAVE. - CALL STFILPOS ; CLEAR INITIAL FILE POSITION (SET TO 0FFFFH). - CALL HOMEDRV ; HOME THE DRIVE. -; -; ENTRY TO LOCATE THE NEXT OCCURENCE OF A FILENAME WITHIN THE -; DIRECTORY. THE DISK IS NOT EXPECTED TO HAVE BEEN CHANGED. IF -; IT WAS, THEN IT WILL BE WRITE PROTECTED. -; -FINDNXT:LD C,0 ; WRITE PROTECT THE DISK IF CHANGED. - CALL NXENTRY ; GET NEXT FILENAME ENTRY IN DIRECTORY. - CALL CKFILPOS ; IS FILE POSITION = 0FFFFH? - JP Z,FNDNXT6 ; YES, EXIT NOW THEN. - LD HL,(SAVEFCB) ; SET (DE) POINTING TO FILENAME TO MATCH. - EX DE,HL - LD A,(DE) - CP 0E5H ; EMPTY DIRECTORY ENTRY? - JP Z,FNDNXT1 ; (* ARE WE TRYING TO RESERECT ERASED ENTRIES? *) - PUSH DE - CALL MOREFLS ; MORE FILES IN DIRECTORY? - POP DE - JP NC,FNDNXT6 ; NO MORE. EXIT NOW. -FNDNXT1:CALL FCB2HL ; GET ADDRESS OF THIS FCB IN DIRECTORY. - LD A,(COUNTER) ; GET NUMBER OF BYTES (CHARACTERS) TO CHECK. - LD C,A - LD B,0 ; INITIALIZE BYTE POSITION COUNTER. -FNDNXT2:LD A,C ; ARE WE DONE WITH THE COMPARE? - OR A - JP Z,FNDNXT5 - LD A,(DE) ; NO, CHECK NEXT BYTE. - CP '?' ; DON'T CARE ABOUT THIS CHARACTER? - JP Z,FNDNXT4 - LD A,B ; GET BYTES POSITION IN FCB. - CP 13 ; DON'T CARE ABOUT THE THIRTEENTH BYTE EITHER. - JP Z,FNDNXT4 - CP 12 ; EXTENT BYTE? - LD A,(DE) - JP Z,FNDNXT3 - SUB (HL) ; OTHERWISE COMPARE CHARACTERS. - AND 7FH - JP NZ,FINDNXT ; NOT THE SAME, CHECK NEXT ENTRY. - JP FNDNXT4 ; SO FAR SO GOOD, KEEP CHECKING. -FNDNXT3:PUSH BC ; CHECK THE EXTENT BYTE HERE. - LD C,(HL) - CALL SAMEXT - POP BC - JP NZ,FINDNXT ; NOT THE SAME, LOOK SOME MORE. -; -; SO FAR THE NAMES COMPARE. BUMP POINTERS TO THE NEXT BYTE -; AND CONTINUE UNTIL ALL (C) CHARACTERS HAVE BEEN CHECKED. -; -FNDNXT4:INC DE ; BUMP POINTERS. - INC HL - INC B - DEC C ; ADJUST CHARACTER COUNTER. - JP FNDNXT2 -FNDNXT5:LD A,(FILEPOS) ; RETURN THE POSITION OF THIS ENTRY. - AND 03H - LD (STATUS),A - LD HL,FNDSTAT - LD A,(HL) - RLA - RET NC - XOR A - LD (HL),A - RET -; -; FILENAME WAS NOT FOUND. SET APPROPRIATE STATUS. -; -FNDNXT6:CALL STFILPOS ; SET (FILEPOS) TO 0FFFFH. - LD A,0FFH ; SAY NOT LOCATED. - JP SETSTAT -; -; ERASE FILES FROM THE DIRECTORY. ONLY THE FIRST BYTE OF THE -; FCB WILL BE AFFECTED. IT IS SET TO (E5). -; -ERAFILE:CALL CHKWPRT ; IS DISK WRITE PROTECTED? - LD C,12 ; ONLY COMPARE FILE NAMES. - CALL FINDFST ; GET FIRST FILE NAME. -ERAFIL1:CALL CKFILPOS ; ANY FOUND? - RET Z ; NOPE, WE MUST BE DONE. - CALL CHKROFL ; IS FILE READ ONLY? - CALL FCB2HL ; NOPE, GET ADDRESS OF FCB AND - LD (HL),0E5H ; SET FIRST BYTE TO 'EMPTY'. - LD C,0 ; CLEAR THE SPACE FROM THE BIT MAP. - CALL SETFILE - CALL DIRWRITE ; NOW WRITE THE DIRECTORY SECTOR BACK OUT. - CALL FINDNXT ; FIND THE NEXT FILE NAME. - JP ERAFIL1 ; AND REPEAT PROCESS. -; -; LOOK THROUGH THE SPACE ALLOCATION MAP (BIT MAP) FOR THE -; NEXT AVAILABLE BLOCK. START SEARCHING AT BLOCK NUMBER (BC-1). -; THE SEARCH PROCEDURE IS TO LOOK FOR AN EMPTY BLOCK THAT IS -; BEFORE THE STARTING BLOCK. IF NOT EMPTY, LOOK AT A LATER -; BLOCK NUMBER. IN THIS WAY, WE RETURN THE CLOSEST EMPTY BLOCK -; ON EITHER SIDE OF THE 'TARGET' BLOCK NUMBER. THIS WILL SPEED -; ACCESS ON RANDOM DEVICES. FOR SERIAL DEVICES, THIS SHOULD BE -; CHANGED TO LOOK IN THE FORWARD DIRECTION FIRST AND THEN START -; AT THE FRONT AND SEARCH SOME MORE. -; -; ON RETURN, (DE)= BLOCK NUMBER THAT IS EMPTY AND (HL) =0 -; IF NO EMPRY BLOCK WAS FOUND. -; -FNDSPACE: - LD D,B ; SET (DE) AS THE BLOCK THAT IS CHECKED. - LD E,C -; -; LOOK BEFORE TARGET BLOCK. REGISTERS (BC) ARE USED AS THE LOWER -; POINTER AND (DE) AS THE UPPER POINTER. -; -FNDSPA1:LD A,C ; IS BLOCK 0 SPECIFIED? - OR B - JP Z,FNDSPA2 - DEC BC ; NOPE, CHECK PREVIOUS BLOCK. - PUSH DE - PUSH BC - CALL CKBITMAP - RRA ; IS THIS BLOCK EMPTY? - JP NC,FNDSPA3 ; YES. USE THIS. -; -; NOTE THAT THE ABOVE LOGIC GETS THE FIRST BLOCK THAT IT FINDS -; THAT IS EMPTY. THUS A FILE COULD BE WRITTEN 'BACKWARD' MAKING -; IT VERY SLOW TO ACCESS. THIS COULD BE CHANGED TO LOOK FOR THE -; FIRST EMPTY BLOCK AND THEN CONTINUE UNTIL THE START OF THIS -; EMPTY SPACE IS LOCATED AND THEN USED THAT STARTING BLOCK. -; THIS SHOULD HELP SPEED UP ACCESS TO SOME FILES ESPECIALLY ON -; A WELL USED DISK WITH LOTS OF FAIRLY SMALL 'HOLES'. -; - POP BC ; NOPE, CHECK SOME MORE. - POP DE -; -; NOW LOOK AFTER TARGET BLOCK. -; -FNDSPA2:LD HL,(DSKSIZE) ; IS BLOCK (DE) WITHIN DISK LIMITS? - LD A,E - SUB L - LD A,D - SBC A,H - JP NC,FNDSPA4 - INC DE ; YES, MOVE ON TO NEXT ONE. - PUSH BC - PUSH DE - LD B,D - LD C,E - CALL CKBITMAP ; CHECK IT. - RRA ; EMPTY? - JP NC,FNDSPA3 - POP DE ; NOPE, CONTINUE SEARCHING. - POP BC - JP FNDSPA1 -; -; EMPTY BLOCK FOUND. SET IT AS USED AND RETURN WITH (HL) -; POINTING TO IT (TRUE?). -; -FNDSPA3:RLA ; RESET BYTE. - INC A ; AND SET BIT 0. - CALL STBMAP1 ; UPDATE BIT MAP. - POP HL ; SET RETURN REGISTERS. - POP DE - RET -; -; FREE BLOCK WAS NOT FOUND. IF (BC) IS NOT ZERO, THEN WE HAVE -; NOT CHECKED ALL OF THE DISK SPACE. -; -FNDSPA4:LD A,C - OR B - JP NZ,FNDSPA1 - LD HL,0 ; SET 'NOT FOUND' STATUS. - RET -; -; MOVE A COMPLETE FCB ENTRY INTO THE DIRECTORY AND WRITE IT. -; -FCBSET: LD C,0 - LD E,32 ; LENGTH OF EACH ENTRY. -; -; MOVE (E) BYTES FROM THE FCB POINTED TO BY (PARAMS) INTO -; FCB IN DIRECTORY STARTING AT RELATIVE BYTE (C). THIS UPDATED -; DIRECTORY BUFFER IS THEN WRITTEN TO THE DISK. -; -UPDATE: PUSH DE - LD B,0 ; SET (BC) TO RELATIVE BYTE POSITION. - LD HL,(PARAMS) ; GET ADDRESS OF FCB. - ADD HL,BC ; COMPUTE STARTING BYTE. - EX DE,HL - CALL FCB2HL ; GET ADDRESS OF FCB TO UPDATE IN DIRECTORY. - POP BC ; SET (C) TO NUMBER OF BYTES TO CHANGE. - CALL DE2HL -UPDATE1:CALL TRKSEC ; DETERMINE THE TRACK AND SECTOR AFFECTED. - JP DIRWRITE ; THEN WRITE THIS SECTOR OUT. -; -; ROUTINE TO CHANGE THE NAME OF ALL FILES ON THE DISK WITH A -; SPECIFIED NAME. THE FCB CONTAINS THE CURRENT NAME AS THE -; FIRST 12 CHARACTERS AND THE NEW NAME 16 BYTES INTO THE FCB. -; -CHGNAMES: - CALL CHKWPRT ; CHECK FOR A WRITE PROTECTED DISK. - LD C,12 ; MATCH FIRST 12 BYTES OF FCB ONLY. - CALL FINDFST ; GET FIRST NAME. - LD HL,(PARAMS) ; GET ADDRESS OF FCB. - LD A,(HL) ; GET USER NUMBER. - LD DE,16 ; MOVE OVER TO DESIRED NAME. - ADD HL,DE - LD (HL),A ; KEEP SAME USER NUMBER. -CHGNAM1:CALL CKFILPOS ; ANY MATCHING FILE FOUND? - RET Z ; NO, WE MUST BE DONE. - CALL CHKROFL ; CHECK FOR READ ONLY FILE. - LD C,16 ; START 16 BYTES INTO FCB. - LD E,12 ; AND UPDATE THE FIRST 12 BYTES OF DIRECTORY. - CALL UPDATE - CALL FINDNXT ; GET TE NEXT FILE NAME. - JP CHGNAM1 ; AND CONTINUE. -; -; UPDATE A FILES ATTRIBUTES. THE PROCEDURE IS TO SEARCH FOR -; EVERY FILE WITH THE SAME NAME AS SHOWN IN FCB (IGNORING BIT 7) -; AND THEN TO UPDATE IT (WHICH INCLUDES BIT 7). NO OTHER CHANGES -; ARE MADE. -; -SAVEATTR: - LD C,12 ; MATCH FIRST 12 BYTES. - CALL FINDFST ; LOOK FOR FIRST FILENAME. -SAVATR1:CALL CKFILPOS ; WAS ONE FOUND? - RET Z ; NOPE, WE MUST BE DONE. - LD C,0 ; YES, UPDATE THE FIRST 12 BYTES NOW. - LD E,12 - CALL UPDATE ; UPDATE FILENAME AND WRITE DIRECTORY. - CALL FINDNXT ; AND GET THE NEXT FILE. - JP SAVATR1 ; THEN CONTINUE UNTIL DONE. -; -; OPEN A FILE (NAME SPECIFIED IN FCB). -; -OPENIT: LD C,15 ; COMPARE THE FIRST 15 BYTES. - CALL FINDFST ; GET THE FIRST ONE IN DIRECTORY. - CALL CKFILPOS ; ANY AT ALL? - RET Z -OPENIT1:CALL SETEXT ; POINT TO EXTENT BYTE WITHIN USERS FCB. - LD A,(HL) ; AND GET IT. - PUSH AF ; SAVE IT AND ADDRESS. - PUSH HL - CALL FCB2HL ; POINT TO FCB IN DIRECTORY. - EX DE,HL - LD HL,(PARAMS) ; THIS IS THE USERS COPY. - LD C,32 ; MOVE IT INTO USERS SPACE. - PUSH DE - CALL DE2HL - CALL SETS2B7 ; SET BIT 7 IN 'S2' BYTE (UNMODIFIED). - POP DE ; NOW GET THE EXTENT BYTE FROM THIS FCB. - LD HL,12 - ADD HL,DE - LD C,(HL) ; INTO (C). - LD HL,15 ; NOW GET THE RECORD COUNT BYTE INTO (B). - ADD HL,DE - LD B,(HL) - POP HL ; KEEP THE SAME EXTENT AS THE USER HAD ORIGINALLY. - POP AF - LD (HL),A - LD A,C ; IS IT THE SAME AS IN THE DIRECTORY FCB? - CP (HL) - LD A,B ; IF YES, THEN USE THE SAME RECORD COUNT. - JP Z,OPENIT2 - LD A,0 ; IF THE USER SPECIFIED AN EXTENT GREATER THAN - JP C,OPENIT2 ; THE ONE IN THE DIRECTORY, THEN SET RECORD COUNT TO 0. - LD A,128 ; OTHERWISE SET TO MAXIMUM. -OPENIT2:LD HL,(PARAMS) ; SET RECORD COUNT IN USERS FCB TO (A). - LD DE,15 - ADD HL,DE ; COMPUTE RELATIVE POSITION. - LD (HL),A ; AND SET THE RECORD COUNT. - RET -; -; MOVE TWO BYTES FROM (DE) TO (HL) IF (AND ONLY IF) (HL) -; POINT TO A ZERO VALUE (16 BIT). -; RETURN WITH ZERO FLAG SET IT (DE) WAS MOVED. REGISTERS (DE) -; AND (HL) ARE NOT CHANGED. HOWEVER (A) IS. -; -MOVEWORD: - LD A,(HL) ; CHECK FOR A ZERO WORD. - INC HL - OR (HL) ; BOTH BYTES ZERO? - DEC HL - RET NZ ; NOPE, JUST RETURN. - LD A,(DE) ; YES, MOVE TWO BYTES FROM (DE) INTO - LD (HL),A ; THIS ZERO SPACE. - INC DE - INC HL - LD A,(DE) - LD (HL),A - DEC DE ; DON'T DISTURB THESE REGISTERS. - DEC HL - RET -; -; GET HERE TO CLOSE A FILE SPECIFIED BY (FCB). -; -CLOSEIT:XOR A ; CLEAR STATUS AND FILE POSITION BYTES. - LD (STATUS),A - LD (FILEPOS),A - LD (FILEPOS+1),A - CALL GETWPRT ; GET WRITE PROTECT BIT FOR THIS DRIVE. - RET NZ ; JUST RETURN IF IT IS SET. - CALL GETS2 ; ELSE GET THE 'S2' BYTE. - AND 80H ; AND LOOK AT BIT 7 (FILE UNMODIFIED?). - RET NZ ; JUST RETURN IF SET. - LD C,15 ; ELSE LOOK UP THIS FILE IN DIRECTORY. - CALL FINDFST - CALL CKFILPOS ; WAS IT FOUND? - RET Z ; JUST RETURN IF NOT. - LD BC,16 ; SET (HL) POINTING TO RECORDS USED SECTION. - CALL FCB2HL - ADD HL,BC - EX DE,HL - LD HL,(PARAMS) ; DO THE SAME FOR USERS SPECIFIED FCB. - ADD HL,BC - LD C,16 ; THIS MANY BYTES ARE PRESENT IN THIS EXTENT. -CLOSEIT1: - LD A,(BIGDISK) ; 8 OR 16 BIT RECORD NUMBERS? - OR A - JP Z,CLOSEIT4 - LD A,(HL) ; JUST 8 BIT. GET ONE FROM USERS FCB. - OR A - LD A,(DE) ; NOW GET ONE FROM DIRECTORY FCB. - JP NZ,CLOSEIT2 - LD (HL),A ; USERS BYTE WAS ZERO. UPDATE FROM DIRECTORY. -CLOSEIT2: - OR A - JP NZ,CLOSEIT3 - LD A,(HL) ; DIRECTORIES BYTE WAS ZERO, UPDATE FROM USERS FCB. - LD (DE),A -CLOSEIT3: - CP (HL) ; IF NEITHER ONE OF THESE BYTES WERE ZERO, - JP NZ,CLOSEIT7 ; THEN CLOSE ERROR IF THEY ARE NOT THE SAME. - JP CLOSEIT5 ; OK SO FAR, GET TO NEXT BYTE IN FCBS. -CLOSEIT4: - CALL MOVEWORD ; UPDATE USERS FCB IF IT IS ZERO. - EX DE,HL - CALL MOVEWORD ; UPDATE DIRECTORIES FCB IF IT IS ZERO. - EX DE,HL - LD A,(DE) ; IF THESE TWO VALUES ARE NO DIFFERENT, - CP (HL) ; THEN A CLOSE ERROR OCCURED. - JP NZ,CLOSEIT7 - INC DE ; CHECK SECOND BYTE. - INC HL - LD A,(DE) - CP (HL) - JP NZ,CLOSEIT7 - DEC C ; REMEMBER 16 BIT VALUES. -CLOSEIT5: - INC DE ; BUMP TO NEXT ITEM IN TABLE. - INC HL - DEC C ; THERE ARE 16 ENTRIES ONLY. - JP NZ,CLOSEIT1 ; CONTINUE IF MORE TO DO. - LD BC,0FFECH ; BACKUP 20 PLACES (EXTENT BYTE). - ADD HL,BC - EX DE,HL - ADD HL,BC - LD A,(DE) - CP (HL) ; DIRECTORY'S EXTENT ALREADY GREATER THAN THE - JP C,CLOSEIT6 ; USERS EXTENT? - LD (HL),A ; NO, UPDATE DIRECTORY EXTENT. - LD BC,3 ; AND UPDATE THE RECORD COUNT BYTE IN - ADD HL,BC ; DIRECTORIES FCB. - EX DE,HL - ADD HL,BC - LD A,(HL) ; GET FROM USER. - LD (DE),A ; AND PUT IN DIRECTORY. -CLOSEIT6: - LD A,0FFH ; SET 'WAS OPEN AND IS NOW CLOSED' BYTE. - LD (CLOSEFLG),A - JP UPDATE1 ; UPDATE THE DIRECTORY NOW. -CLOSEIT7: - LD HL,STATUS ; SET RETURN STATUS AND THEN RETURN. - DEC (HL) - RET -; -; ROUTINE TO GET THE NEXT EMPTY SPACE IN THE DIRECTORY. IT -; WILL THEN BE CLEARED FOR USE. -; -GETEMPTY: - CALL CHKWPRT ; MAKE SURE DISK IS NOT WRITE PROTECTED. - LD HL,(PARAMS) ; SAVE CURRENT PARAMETERS (FCB). - PUSH HL - LD HL,EMPTYFCB ; USE SPECIAL ONE FOR EMPTY SPACE. - LD (PARAMS),HL - LD C,1 ; SEARCH FOR FIRST EMPTY SPOT IN DIRECTORY. - CALL FINDFST ; (* ONLY CHECK FIRST BYTE *) - CALL CKFILPOS ; NONE? - POP HL - LD (PARAMS),HL ; RESTORE ORIGINAL FCB ADDRESS. - RET Z ; RETURN IF NO MORE SPACE. - EX DE,HL - LD HL,15 ; POINT TO NUMBER OF RECORDS FOR THIS FILE. - ADD HL,DE - LD C,17 ; AND CLEAR ALL OF THIS SPACE. - XOR A -GETMT1: LD (HL),A - INC HL - DEC C - JP NZ,GETMT1 - LD HL,13 ; CLEAR THE 'S1' BYTE ALSO. - ADD HL,DE - LD (HL),A - CALL CHKNMBR ; KEEP (SCRATCH1) WITHIN BOUNDS. - CALL FCBSET ; WRITE OUT THIS FCB ENTRY TO DIRECTORY. - JP SETS2B7 ; SET 'S2' BYTE BIT 7 (UNMODIFIED AT PRESENT). -; -; ROUTINE TO CLOSE THE CURRENT EXTENT AND OPEN THE NEXT ONE -; FOR READING. -; -GETNEXT:XOR A - LD (CLOSEFLG),A ; CLEAR CLOSE FLAG. - CALL CLOSEIT ; CLOSE THIS EXTENT. - CALL CKFILPOS - RET Z ; NOT THERE??? - LD HL,(PARAMS) ; GET EXTENT BYTE. - LD BC,12 - ADD HL,BC - LD A,(HL) ; AND INCREMENT IT. - INC A - AND 1FH ; KEEP WITHIN RANGE 0-31. - LD (HL),A - JP Z,GTNEXT1 ; OVERFLOW? - LD B,A ; MASK EXTENT BYTE. - LD A,(EXTMASK) - AND B - LD HL,CLOSEFLG ; CHECK CLOSE FLAG (0FFH IS OK). - AND (HL) - JP Z,GTNEXT2 ; IF ZERO, WE MUST READ IN NEXT EXTENT. - JP GTNEXT3 ; ELSE, IT IS ALREADY IN MEMORY. -GTNEXT1:LD BC,2 ; POINT TO THE 'S2' BYTE. - ADD HL,BC - INC (HL) ; AND BUMP IT. - LD A,(HL) ; TOO MANY EXTENTS? - AND 0FH - JP Z,GTNEXT5 ; YES, SET ERROR CODE. -; -; GET HERE TO OPEN THE NEXT EXTENT. -; -GTNEXT2:LD C,15 ; SET TO CHECK FIRST 15 BYTES OF FCB. - CALL FINDFST ; FIND THE FIRST ONE. - CALL CKFILPOS ; NONE AVAILABLE? - JP NZ,GTNEXT3 - LD A,(R.DWRTFLG) ; NO EXTENT PRESENT. CAN WE OPEN AN EMPTY ONE? - INC A ; 0FFH MEANS READING (SO NOT POSSIBLE). - JP Z,GTNEXT5 ; OR AN ERROR. - CALL GETEMPTY ; WE ARE WRITING, GET AN EMPTY ENTRY. - CALL CKFILPOS ; NONE? - JP Z,GTNEXT5 ; ERROR IF TRUE. - JP GTNEXT4 ; ELSE WE ARE ALMOST DONE. -GTNEXT3:CALL OPENIT1 ; OPEN THIS EXTENT. -GTNEXT4:CALL STRDATA ; MOVE IN UPDATED DATA (REC #, EXTENT #, ETC.) - XOR A ; CLEAR STATUS AND RETURN. - JP SETSTAT -; -; ERROR IN EXTENDING THE FILE. TOO MANY EXTENTS WERE NEEDED -; OR NOT ENOUGH SPACE ON THE DISK. -; -GTNEXT5:CALL IOERR1 ; SET ERROR CODE, CLEAR BIT 7 OF 'S2' - JP SETS2B7 ; SO THIS IS NOT WRITTEN ON A CLOSE. -; -; READ A S.EQUENTIAL FILE. -; -RDSEQ: LD A,1 ; SET S.EQUENTIAL ACCESS MODE. - LD (MODE),A -RDSEQ1: LD A,0FFH ; DON'T ALLOW READING UNWRITTEN SPACE. - LD (R.DWRTFLG),A - CALL STRDATA ; PUT REC# AND EXT# INTO FCB. - LD A,(SAVNREC) ; GET NEXT RECORD TO READ. - LD HL,SAVNXT ; GET NUMBER OF RECORDS IN EXTENT. - CP (HL) ; WITHIN THIS EXTENT? - JP C,RDSEQ2 - CP 128 ; NO. IS THIS EXTENT FULLY USED? - JP NZ,RDSEQ3 ; NO. END-OF-FILE. - CALL GETNEXT ; YES, OPEN THE NEXT ONE. - XOR A ; RESET NEXT RECORD TO READ. - LD (SAVNREC),A - LD A,(STATUS) ; CHECK ON OPEN, SUCCESSFUL? - OR A - JP NZ,RDSEQ3 ; NO, ERROR. -RDSEQ2: CALL COMBLK ; OK. COMPUTE BLOCK NUMBER TO READ. - CALL CHKBLK ; CHECK IT. WITHIN BOUNDS? - JP Z,RDSEQ3 ; NO, ERROR. - CALL LOGICAL ; CONVERT (BLKNMBR) TO LOGICAL SECTOR (128 BYTE). - CALL TRKSEC1 ; SET THE TRACK AND SECTOR FOR THIS BLOCK #. - CALL DOREAD ; AND READ IT. - JP SETNREC ; AND SET THE NEXT RECORD TO BE ACCESSED. -; -; READ ERROR OCCURED. SET STATUS AND RETURN. -; -RDSEQ3: JP IOERR1 -; -; WRITE THE NEXT S.EQUENTIAL RECORD. -; -WTSEQ: LD A,1 ; SET S.EQUENTIAL ACCESS MODE. - LD (MODE),A -WTSEQ1: LD A,0 ; ALLOW AN ADDITION EMPTY EXTENT TO BE OPENED. - LD (R.DWRTFLG),A - CALL CHKWPRT ; CHECK WRITE PROTECT STATUS. - LD HL,(PARAMS) - CALL CKROF1 ; CHECK FOR READ ONLY FILE, (HL) ALREADY SET TO FCB. - CALL STRDATA ; PUT UPDATED DATA INTO FCB. - LD A,(SAVNREC) ; GET RECORD NUMBER TO WRITE. - CP 128 ; WITHIN RANGE? - JP NC,IOERR1 ; NO, ERROR(?). - CALL COMBLK ; COMPUTE BLOCK NUMBER. - CALL CHKBLK ; CHECK NUMBER. - LD C,0 ; IS THERE ONE TO WRITE TO? - JP NZ,WTSEQ6 ; YES, GO DO IT. - CALL GETBLOCK ; GET NEXT BLOCK NUMBER WITHIN FCB TO USE. - LD (RELBLOCK),A ; AND SAVE. - LD BC,0 ; START LOOKING FOR SPACE FROM THE START - OR A ; IF NONE ALLOCATED AS YET. - JP Z,WTSEQ2 - LD C,A ; EXTRACT PREVIOUS BLOCK NUMBER FROM FCB - DEC BC ; SO WE CAN BE CLOSEST TO IT. - CALL EXTBLK - LD B,H - LD C,L -WTSEQ2: CALL FNDSPACE ; FIND THE NEXT EMPTY BLOCK NEAREST NUMBER (BC). - LD A,L ; CHECK FOR A ZERO NUMBER. - OR H - JP NZ,WTSEQ3 - LD A,2 ; NO MORE SPACE? - JP SETSTAT -WTSEQ3: LD (BLKNMBR),HL ; SAVE BLOCK NUMBER TO ACCESS. - EX DE,HL ; PUT BLOCK NUMBER INTO (DE). - LD HL,(PARAMS) ; NOW WE MUST UPDATE THE FCB FOR THIS - LD BC,16 ; NEWLY ALLOCATED BLOCK. - ADD HL,BC - LD A,(BIGDISK) ; 8 OR 16 BIT BLOCK NUMBERS? - OR A - LD A,(RELBLOCK) ; (* UPDATE THIS ENTRY *) - JP Z,WTSEQ4 ; ZERO MEANS 16 BIT ONES. - CALL ADDA2HL ; (HL)=(HL)+(A) - LD (HL),E ; STORE NEW BLOCK NUMBER. - JP WTSEQ5 -WTSEQ4: LD C,A ; COMPUTE SPOT IN THIS 16 BIT TABLE. - LD B,0 - ADD HL,BC - ADD HL,BC - LD (HL),E ; STUFF BLOCK NUMBER (DE) THERE. - INC HL - LD (HL),D -WTSEQ5: LD C,2 ; SET (C) TO INDICATE WRITING TO UN-USED DISK SPACE. -WTSEQ6: LD A,(STATUS) ; ARE WE OK SO FAR? - OR A - RET NZ - PUSH BC ; YES, SAVE WRITE FLAG FOR BIOS (REGISTER C). - CALL LOGICAL ; CONVERT (BLKNMBR) OVER TO LOICAL SECTORS. - LD A,(MODE) ; GET ACCESS MODE FLAG (1=S.EQUENTIAL, - DEC A ; 0=RANDOM, 2=SPECIAL?). - DEC A - JP NZ,WTSEQ9 -; -; SPECIAL RANDOM I/O FROM FUNCTION #40. MAYBE FOR M/PM, BUT THE -; CURRENT BLOCK, IF IT HAS NOT BEEN WRITTEN TO, WILL BE ZEROED -; OUT AND THEN WRITTEN (REASON?). -; - POP BC - PUSH BC - LD A,C ; GET WRITE STATUS FLAG (2=WRITING UNUSED SPACE). - DEC A - DEC A - JP NZ,WTSEQ9 - PUSH HL - LD HL,(DIRBUF) ; ZERO OUT THE DIRECTORY BUFFER. - LD D,A ; NOTE THAT (A) IS ZERO HERE. -WTSEQ7: LD (HL),A - INC HL - INC D ; DO 128 BYTES. - JP P,WTSEQ7 - CALL DIRDMA ; TELL THE BIOS THE DMA ADDRESS FOR DIRECTORY ACCESS. - LD HL,(LOGSECT) ; GET SECTOR THAT STARTS CURRENT BLOCK. - LD C,2 ; SET 'WRITING TO UNUSED SPACE' FLAG. -WTSEQ8: LD (BLKNMBR),HL ; SAVE SECTOR TO WRITE. - PUSH BC - CALL TRKSEC1 ; DETERMINE ITS TRACK AND SECTOR NUMBERS. - POP BC - CALL DOWRITE ; NOW WRITE OUT 128 BYTES OF ZEROS. - LD HL,(BLKNMBR) ; GET SECTOR NUMBER. - LD C,0 ; SET NORMAL WRITE FLAG. - LD A,(BLKMASK) ; DETERMINE IF WE HAVE WRITTEN THE ENTIRE - LD B,A ; PHYSICAL BLOCK. - AND L - CP B - INC HL ; PREPARE FOR THE NEXT ONE. - JP NZ,WTSEQ8 ; CONTINUE UNTIL (BLKMASK+1) SECTORS WRITTEN. - POP HL ; RESET NEXT SECTOR NUMBER. - LD (BLKNMBR),HL - CALL DEFDMA ; AND RESET DMA ADDRESS. -; -; NORMAL DISK WRITE. SET THE DESIRED TRACK AND SECTOR THEN -; DO THE ACTUAL WRITE. -; -WTSEQ9: CALL TRKSEC1 ; DETERMINE TRACK AND SECTOR FOR THIS WRITE. - POP BC ; GET WRITE STATUS FLAG. - PUSH BC - CALL DOWRITE ; AND WRITE THIS OUT. - POP BC - LD A,(SAVNREC) ; GET NUMBER OF RECORDS IN FILE. - LD HL,SAVNXT ; GET LAST RECORD WRITTEN. - CP (HL) - JP C,WTSEQ10 - LD (HL),A ; WE HAVE TO UPDATE RECORD COUNT. - INC (HL) - LD C,2 -; -;* THIS AREA HAS BEEN PATCHED TO CORRECT DISK UPDATE PROBLEM -;* WHEN USING BLOCKING AND DE-BLOCKING IN THE BIOS. -; -WTSEQ10:NOP ; WAS 'DCR C' - NOP ; WAS 'DCR C' - LD HL,0 ; WAS 'JNZ WTSEQ99' -; -; * END OF PATCH. -; - PUSH AF - CALL GETS2 ; SET 'EXTENT WRITTEN TO' FLAG. - AND 7FH ; (* CLEAR BIT 7 *) - LD (HL),A - POP AF ; GET RECORD COUNT FOR THIS EXTENT. -WTSEQ99:CP 127 ; IS IT FULL? - JP NZ,WTSEQ12 - LD A,(MODE) ; YES, ARE WE IN S.EQUENTIAL MODE? - CP 1 - JP NZ,WTSEQ12 - CALL SETNREC ; YES, SET NEXT RECORD NUMBER. - CALL GETNEXT ; AND GET NEXT EMPTY SPACE IN DIRECTORY. - LD HL,STATUS ; OK? - LD A,(HL) - OR A - JP NZ,WTSEQ11 - DEC A ; YES, SET RECORD COUNT TO -1. - LD (SAVNREC),A -WTSEQ11:LD (HL),0 ; CLEAR STATUS. -WTSEQ12:JP SETNREC ; SET NEXT RECORD TO ACCESS. -; -; FOR RANDOM I/O, SET THE FCB FOR THE DESIRED RECORD NUMBER -; BASED ON THE 'R0,R1,R2' BYTES. THESE BYTES IN THE FCB ARE -; USED AS FOLLOWS: -; -; FCB+35 FCB+34 FCB+33 -; | 'R-2' | 'R-1' | 'R-0' | -; |7 0 | 7 0 | 7 0| -; |0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0| -; | OVERFLOW | | EXTRA | EXTENT | RECORD # | -; | ______________| |_EXTENT|__NUMBER___|_____________| -; ALSO 'S2' -; -; ON ENTRY, REGISTER (C) CONTAINS 0FFH IF THIS IS A READ -; AND THUS WE CAN NOT ACCESS UNWRITTEN DISK SPACE. OTHERWISE, -; ANOTHER EXTENT WILL BE OPENED (FOR WRITING) IF R.EQUIRED. -; -POSITION: - XOR A ; SET RANDOM I/O FLAG. - LD (MODE),A -; -; SPECIAL ENTRY (FUNCTION #40). M/PM ? -; -POSITN1:PUSH BC ; SAVE READ/WRITE FLAG. - LD HL,(PARAMS) ; GET ADDRESS OF FCB. - EX DE,HL - LD HL,33 ; NOW GET BYTE 'R0'. - ADD HL,DE - LD A,(HL) - AND 7FH ; KEEP BITS 0-6 FOR THE RECORD NUMBER TO ACCESS. - PUSH AF - LD A,(HL) ; NOW GET BIT 7 OF 'R0' AND BITS 0-3 OF 'R1'. - RLA - INC HL - LD A,(HL) - RLA - AND 1FH ; AND SAVE THIS IN BITS 0-4 OF (C). - LD C,A ; THIS IS THE EXTENT BYTE. - LD A,(HL) ; NOW GET THE EXTRA EXTENT BYTE. - RRA - RRA - RRA - RRA - AND 0FH - LD B,A ; AND SAVE IT IN (B). - POP AF ; GET RECORD NUMBER BACK TO (A). - INC HL ; CHECK OVERFLOW BYTE 'R2'. - LD L,(HL) - INC L - DEC L - LD L,6 ; PREPARE FOR ERROR. - JP NZ,POSITN5 ; OUT OF DISK SPACE ERROR. - LD HL,32 ; STORE RECORD NUMBER INTO FCB. - ADD HL,DE - LD (HL),A - LD HL,12 ; AND NOW CHECK THE EXTENT BYTE. - ADD HL,DE - LD A,C - SUB (HL) ; SAME EXTENT AS BEFORE? - JP NZ,POSITN2 - LD HL,14 ; YES, CHECK EXTRA EXTENT BYTE 'S2' ALSO. - ADD HL,DE - LD A,B - SUB (HL) - AND 7FH - JP Z,POSITN3 ; SAME, WE ARE ALMOST DONE THEN. -; -; GET HERE WHEN ANOTHER EXTENT IS R.EQUIRED. -; -POSITN2:PUSH BC - PUSH DE - CALL CLOSEIT ; CLOSE CURRENT EXTENT. - POP DE - POP BC - LD L,3 ; PREPARE FOR ERROR. - LD A,(STATUS) - INC A - JP Z,POSITN4 ; CLOSE ERROR. - LD HL,12 ; PUT DESIRED EXTENT INTO FCB NOW. - ADD HL,DE - LD (HL),C - LD HL,14 ; AND STORE EXTRA EXTENT BYTE 'S2'. - ADD HL,DE - LD (HL),B - CALL OPENIT ; TRY AND GET THIS EXTENT. - LD A,(STATUS) ; WAS IT THERE? - INC A - JP NZ,POSITN3 - POP BC ; NO. CAN WE CREATE A NEW ONE (WRITING?). - PUSH BC - LD L,4 ; PREPARE FOR ERROR. - INC C - JP Z,POSITN4 ; NOPE, READING UNWRITTEN SPACE ERROR. - CALL GETEMPTY ; YES WE CAN, TRY TO FIND SPACE. - LD L,5 ; PREPARE FOR ERROR. - LD A,(STATUS) - INC A - JP Z,POSITN4 ; OUT OF SPACE? -; -; NORMAL RETURN LOCATION. CLEAR ERROR CODE AND RETURN. -; -POSITN3:POP BC ; RESTORE STACK. - XOR A ; AND CLEAR ERROR CODE BYTE. - JP SETSTAT -; -; ERROR. SET THE 'S2' BYTE TO INDICATE THIS (WHY?). -; -POSITN4:PUSH HL - CALL GETS2 - LD (HL),0C0H - POP HL -; -; RETURN WITH ERROR CODE (PRESENTLY IN L). -; -POSITN5:POP BC - LD A,L ; GET ERROR CODE. - LD (STATUS),A - JP SETS2B7 -; -; READ A RANDOM RECORD. -; -READRAN:LD C,0FFH ; SET 'READ' STATUS. - CALL POSITION ; POSITION THE FILE TO PROPER RECORD. - CALL Z,RDSEQ1 ; AND READ IT AS USUAL (IF NO ERRORS). - RET -; -; WRITE TO A RANDOM RECORD. -; -WRITERAN: - LD C,0 ; SET 'WRITING' FLAG. - CALL POSITION ; POSITION THE FILE TO PROPER RECORD. - CALL Z,WTSEQ1 ; AND WRITE AS USUAL (IF NO ERRORS). - RET -; -; COMPUTE THE RANDOM RECORD NUMBER. ENTER WITH (HL) POINTING -; TO A FCB AN (DE) CONTAINS A RELATIVE LOCATION OF A RECORD -; NUMBER. ON EXIT, (C) CONTAINS THE 'R0' BYTE, (B) THE 'R1' -; BYTE, AND (A) THE 'R2' BYTE. -; -; ON RETURN, THE ZERO FLAG IS SET IF THE RECORD IS WITHIN -; BOUNDS. OTHERWISE, AN OVERFLOW OCCURED. -; -COMPRAND: - EX DE,HL ; SAVE FCB POINTER IN (DE). - ADD HL,DE ; COMPUTE RELATIVE POSITION OF RECORD #. - LD C,(HL) ; GET RECORD NUMBER INTO (BC). - LD B,0 - LD HL,12 ; NOW GET EXTENT. - ADD HL,DE - LD A,(HL) ; COMPUTE (BC)=(RECORD #)+(EXTENT)*128. - RRCA ; MOVE LOWER BIT INTO BIT 7. - AND 80H ; AND IGNORE ALL OTHER BITS. - ADD A,C ; ADD TO OUR RECORD NUMBER. - LD C,A - LD A,0 ; TAKE CARE OF ANY CARRY. - ADC A,B - LD B,A - LD A,(HL) ; NOW GET THE UPPER BITS OF EXTENT INTO - RRCA ; BIT POSITIONS 0-3. - AND 0FH ; AND IGNORE ALL OTHERS. - ADD A,B ; ADD THIS IN TO 'R1' BYTE. - LD B,A - LD HL,14 ; GET THE 'S2' BYTE (EXTRA EXTENT). - ADD HL,DE - LD A,(HL) - ADD A,A ; AND SHIFT IT LEFT 4 BITS (BITS 4-7). - ADD A,A - ADD A,A - ADD A,A - PUSH AF ; SAVE CARRY FLAG (BIT 0 OF FLAG BYTE). - ADD A,B ; NOW ADD EXTRA EXTENT INTO 'R1'. - LD B,A - PUSH AF ; AND SAVE CARRY (OVERFLOW BYTE 'R2'). - POP HL ; BIT 0 OF (L) IS THE OVERFLOW INDICATOR. - LD A,L - POP HL ; AND SAME FOR FIRST CARRY FLAG. - OR L ; EITHER ONE OF THESE SET? - AND 01H ; ONLY CHECK THE CARRY FLAGS. - RET -; -; ROUTINE TO SETUP THE FCB (BYTES 'R0', 'R1', 'R2') TO -; REFLECT THE LAST RECORD USED FOR A RANDOM (OR OTHER) FILE. -; THIS READS THE DIRECTORY AND LOOKS AT ALL EXTENTS COMPUTING -; THE LARGERST RECORD NUMBER FOR EACH AND KEEPING THE MAXIMUM -; VALUE ONLY. THEN 'R0', 'R1', AND 'R2' WILL REFLECT THIS -; MAXIMUM RECORD NUMBER. THIS IS USED TO COMPUTE THE SPACE USED -; BY A RANDOM FILE. -; -RANSIZE:LD C,12 ; LOOK THRU DIRECTORY FOR FIRST ENTRY WITH - CALL FINDFST ; THIS NAME. - LD HL,(PARAMS) ; ZERO OUT THE 'R0, R1, R2' BYTES. - LD DE,33 - ADD HL,DE - PUSH HL - LD (HL),D ; NOTE THAT (D)=0. - INC HL - LD (HL),D - INC HL - LD (HL),D -RANSIZ1:CALL CKFILPOS ; IS THERE AN EXTENT TO PROCESS? - JP Z,RANSIZ3 ; NO, WE ARE DONE. - CALL FCB2HL ; SET (HL) POINTING TO PROPER FCB IN DIR. - LD DE,15 ; POINT TO LAST RECORD IN EXTENT. - CALL COMPRAND ; AND COMPUTE RANDOM PARAMETERS. - POP HL - PUSH HL ; NOW CHECK THESE VALUES AGAINST THOSE - LD E,A ; ALREADY IN FCB. - LD A,C ; THE CARRY FLAG WILL BE SET IF THOSE - SUB (HL) ; IN THE FCB REPRESENT A LARGER SIZE THAN - INC HL ; THIS EXTENT DOES. - LD A,B - SBC A,(HL) - INC HL - LD A,E - SBC A,(HL) - JP C,RANSIZ2 - LD (HL),E ; WE FOUND A LARGER (IN SIZE) EXTENT. - DEC HL ; STUFF THESE VALUES INTO FCB. - LD (HL),B - DEC HL - LD (HL),C -RANSIZ2:CALL FINDNXT ; NOW GET THE NEXT EXTENT. - JP RANSIZ1 ; CONTINUE TIL ALL DONE. -RANSIZ3:POP HL ; WE ARE DONE, RESTORE THE STACK AND - RET ; RETURN. -; -; FUNCTION TO RETURN THE RANDOM RECORD POSITION OF A GIVEN -; FILE WHICH HAS BEEN READ IN S.EQUENTIAL MODE UP TO NOW. -; -SETRAN: LD HL,(PARAMS) ; POINT TO FCB. - LD DE,32 ; AND TO LAST USED RECORD. - CALL COMPRAND ; COMPUTE RANDOM POSITION. - LD HL,33 ; NOW STUFF THESE VALUES INTO FCB. - ADD HL,DE - LD (HL),C ; MOVE 'R0'. - INC HL - LD (HL),B ; AND 'R1'. - INC HL - LD (HL),A ; AND LASTLY 'R2'. - RET -; -; THIS ROUTINE SELECT THE DRIVE SPECIFIED IN (ACTIVE) AND -; UPDATE THE LOGIN VECTOR AND BITMAP TABLE IF THIS DRIVE WAS -; NOT ALREADY ACTIVE. -; -LOGINDRV: - LD HL,(LOGIN) ; GET THE LOGIN VECTOR. - LD A,(ACTIVE) ; GET THE DEFAULT DRIVE. - LD C,A - CALL SHIFTR ; POSITION ACTIVE BIT FOR THIS DRIVE - PUSH HL ; INTO BIT 0. - EX DE,HL - CALL SELECT ; SELECT THIS DRIVE. - POP HL - CALL Z,SLCTERR ; VALID DRIVE? - LD A,L ; IS THIS A NEWLY ACTIVATED DRIVE? - RRA - RET C - LD HL,(LOGIN) ; YES, UPDATE THE LOGIN VECTOR. - LD C,L - LD B,H - CALL SETBIT - LD (LOGIN),HL ; AND SAVE. - JP BITMAP ; NOW UPDATE THE BITMAP. -; -; FUNCTION TO SET THE ACTIVE DISK NUMBER. -; -SETDSK: LD A,(EPARAM) ; GET PARAMETER PASSED AND SEE IF THIS - LD HL,ACTIVE ; REPRESENTS A CHANGE IN DRIVES. - CP (HL) - RET Z - LD (HL),A ; YES IT DOES, LOG IT IN. - JP LOGINDRV -; -; THIS IS THE 'AUTO DISK SELECT' ROUTINE. THE FIRSST BYTE -; OF THE FCB IS EXAMINED FOR A DRIVE SPECIFICATION. IF NON -; ZERO THEN THE DRIVE WILL BE SELECTED AND LOGED IN. -; -AUTOSEL:LD A,0FFH ; SAY 'AUTO-SELECT ACTIVATED'. - LD (AUTO),A - LD HL,(PARAMS) ; GET DRIVE SPECIFIED. - LD A,(HL) - AND 1FH ; LOOK AT LOWER 5 BITS. - DEC A ; ADJUST FOR (1=A, 2=B) ETC. - LD (EPARAM),A ; AND SAVE FOR THE SELECT ROUTINE. - CP 1EH ; CHECK FOR 'NO CHANGE' CONDITION. - JP NC,AUTOSL1 ; YES, DON'T CHANGE. - LD A,(ACTIVE) ; WE MUST CHANGE, SAVE CURRENTLY ACTIVE - LD (OLDDRV),A ; DRIVE. - LD A,(HL) ; AND SAVE FIRST BYTE OF FCB ALSO. - LD (AUTOFLAG),A ; THIS MUST BE NON-ZERO. - AND 0E0H ; WHATS THIS FOR (BITS 6,7 ARE USED FOR - LD (HL),A ; SOMETHING)? - CALL SETDSK ; SELECT AND LOG IN THIS DRIVE. -AUTOSL1:LD A,(USERNO) ; MOVE USER NUMBER INTO FCB. - LD HL,(PARAMS) ; (* UPPER HALF OF FIRST BYTE *) - OR (HL) - LD (HL),A - RET ; AND RETURN (ALL DONE). -; -; FUNCTION TO RETURN THE CURRENT CP/M VERSION NUMBER. -; -GETVER: LD A,022H ; VERSION 2.2 - JP SETSTAT -; -; FUNCTION TO RESET THE DISK SYSTEM. -; -RSTDSK: LD HL,0 ; CLEAR WRITE PROTECT STATUS AND LOG - LD (WRTPRT),HL ; IN VECTOR. - LD (LOGIN),HL - XOR A ; SELECT DRIVE 'A'. - LD (ACTIVE),A - LD HL,TBUFF ; SETUP DEFAULT DMA ADDRESS. - LD (USERDMA),HL - CALL DEFDMA - JP LOGINDRV ; NOW LOG IN DRIVE 'A'. -; -; FUNCTION TO OPEN A SPECIFIED FILE. -; -OPENFIL:CALL CLEARS2 ; CLEAR 'S2' BYTE. - CALL AUTOSEL ; SELECT PROPER DISK. - JP OPENIT ; AND OPEN THE FILE. -; -; FUNCTION TO CLOSE A SPECIFIED FILE. -; -CLOSEFIL: - CALL AUTOSEL ; SELECT PROPER DISK. - JP CLOSEIT ; AND CLOSE THE FILE. -; -; FUNCTION TO RETURN THE FIRST OCCURENCE OF A SPECIFIED FILE -; NAME. IF THE FIRST BYTE OF THE FCB IS '?' THEN THE NAME WILL -; NOT BE CHECKED (GET THE FIRST ENTRY NO MATTER WHAT). -; -GETFST: LD C,0 ; PREPARE FOR SPECIAL SEARCH. - EX DE,HL - LD A,(HL) ; IS FIRST BYTE A '?'? - CP '?' - JP Z,GETFST1 ; YES, JUST GET VERY FIRST ENTRY (ZERO LENGTH MATCH). - CALL SETEXT ; GET THE EXTENSION BYTE FROM FCB. - LD A,(HL) ; IS IT '?'? IF YES, THEN WE WANT - CP '?' ; AN ENTRY WITH A SPECIFIC 'S2' BYTE. - CALL NZ,CLEARS2 ; OTHERWISE, LOOK FOR A ZERO 'S2' BYTE. - CALL AUTOSEL ; SELECT PROPER DRIVE. - LD C,15 ; COMPARE BYTES 0-14 IN FCB (12&13 EXCLUDED). -GETFST1:CALL FINDFST ; FIND AN ENTRY AND THEN MOVE IT INTO - JP MOVEDIR ; THE USERS DMA SPACE. -; -; FUNCTION TO RETURN THE NEXT OCCURENCE OF A FILE NAME. -; -GETNXT: LD HL,(SAVEFCB) ; RESTORE POINTERS. NOTE THAT NO - LD (PARAMS),HL ; OTHER .DBOS CALLS ARE ALLOWED. - CALL AUTOSEL ; NO ERROR WILL BE RETURNED, BUT THE - CALL FINDNXT ; RESULTS WILL BE WRONG. - JP MOVEDIR -; -; FUNCTION TO DELETE A FILE BY NAME. -; -DELFILE:CALL AUTOSEL ; SELECT PROPER DRIVE. - CALL ERAFILE ; ERASE THE FILE. - JP STSTATUS ; SET STATUS AND RETURN. -; -; FUNCTION TO EXECUTE A S.EQUENTIAL READ OF THE SPECIFIED -; RECORD NUMBER. -; -READSEQ:CALL AUTOSEL ; SELECT PROPER DRIVE THEN READ. - JP RDSEQ -; -; FUNCTION TO WRITE THE NET S.EQUENTIAL RECORD. -; -WRTSEQ: CALL AUTOSEL ; SELECT PROPER DRIVE THEN WRITE. - JP WTSEQ -; -; CREATE A FILE FUNCTION. -; -FCREATE:CALL CLEARS2 ; CLEAR THE 'S2' BYTE ON ALL CREATES. - CALL AUTOSEL ; SELECT PROPER DRIVE AND GET THE NEXT - JP GETEMPTY ; EMPTY DIRECTORY SPACE. -; -; FUNCTION TO RENAME A FILE. -; -RENFILE:CALL AUTOSEL ; SELECT PROPER DRIVE AND THEN SWITCH - CALL CHGNAMES ; FILE NAMES. - JP STSTATUS -; -; FUNCTION TO RETURN THE LOGIN VECTOR. -; -GETLOG: LD HL,(LOGIN) - JP GETPRM1 -; -; FUNCTION TO RETURN THE CURRENT DISK ASSIGNMENT. -; -GETCRNT:LD A,(ACTIVE) - JP SETSTAT -; -; FUNCTION TO SET THE DMA ADDRESS. -; -PUTDMA: EX DE,HL - LD (USERDMA),HL ; SAVE IN OUR SPACE AND THEN GET TO - JP DEFDMA ; THE BIOS WITH THIS ALSO. -; -; FUNCTION TO RETURN THE ALLOCATION VECTOR. -; -GETALOC:LD HL,(ALOCVECT) - JP GETPRM1 -; -; FUNCTION TO RETURN THE READ-ONLY STATUS VECTOR. -; -GETROV: LD HL,(WRTPRT) - JP GETPRM1 -; -; FUNCTION TO SET THE FILE ATTRIBUTES (READ-ONLY, SYSTEM). -; -SETATTR:CALL AUTOSEL ; SELECT PROPER DRIVE THEN SAVE ATTRIBUTES. - CALL SAVEATTR - JP STSTATUS -; -; FUNCTION TO RETURN THE ADDRESS OF THE DISK PARAMETER BLOCK -; FOR THE CURRENT DRIVE. -; -GETPARM:LD HL,(DISKPB) -GETPRM1:LD (STATUS),HL - RET -; -; FUNCTION TO GET OR SET THE USER NUMBER. IF (E) WAS (FF) -; THEN THIS IS A R.EQUEST TO RETURN THE CURRENT USER NUMBER. -; ELSE SET THE USER NUMBER FROM (E). -; -GETUSER:LD A,(EPARAM) ; GET PARAMETER. - CP 0FFH ; GET USER NUMBER? - JP NZ,SETUSER - LD A,(USERNO) ; YES, JUST DO IT. - JP SETSTAT -SETUSER:AND 1FH ; NO, WE SHOULD SET IT INSTEAD. KEEP LOW - LD (USERNO),A ; BITS (0-4) ONLY. - RET -; -; FUNCTION TO READ A RANDOM RECORD FROM A FILE. -; -RDRANDOM: - CALL AUTOSEL ; SELECT PROPER DRIVE AND READ. - JP READRAN -; -; FUNCTION TO COMPUTE THE FILE SIZE FOR RANDOM FILES. -; -WTRANDOM: - CALL AUTOSEL ; SELECT PROPER DRIVE AND WRITE. - JP WRITERAN -; -; FUNCTION TO COMPUTE THE SIZE OF A RANDOM FILE. -; -FILESIZE: - CALL AUTOSEL ; SELECT PROPER DRIVE AND CHECK FILE LENGTH - JP RANSIZE -; -; FUNCTION #37. THIS ALLOWS A PROGRAM TO LOG OFF ANY DRIVES. -; ON ENTRY, SET (DE) TO CONTAIN A WORD WITH BITS SET FOR THOSE -; DRIVES THAT ARE TO BE LOGGED OFF. THE LOG-IN VECTOR AND THE -; WRITE PROTECT VECTOR WILL BE UPDATED. THIS MUST BE A M/PM -; SPECIAL FUNCTION. -; -LOGOFF: LD HL,(PARAMS) ; GET DRIVES TO LOG OFF. - LD A,L ; FOR EACH BIT THAT IS SET, WE WANT - CPL ; TO CLEAR THAT BIT IN (LOGIN) - LD E,A ; AND (WRTPRT). - LD A,H - CPL - LD HL,(LOGIN) ; RESET THE LOGIN VECTOR. - AND H - LD D,A - LD A,L - AND E - LD E,A - LD HL,(WRTPRT) - EX DE,HL - LD (LOGIN),HL ; AND SAVE. - LD A,L ; NOW DO THE WRITE PROTECT VECTOR. - AND E - LD L,A - LD A,H - AND D - LD H,A - LD (WRTPRT),HL ; AND SAVE. ALL DONE. - RET -; -; GET HERE TO RETURN TO THE USER. -; -GOBACK: LD A,(AUTO) ; WAS AUTO SELECT ACTIVATED? - OR A - JP Z,GOBACK1 - LD HL,(PARAMS) ; YES, BUT WAS A CHANGE MADE? - LD (HL),0 ; (* RESET FIRST BYTE OF FCB *) - LD A,(AUTOFLAG) - OR A - JP Z,GOBACK1 - LD (HL),A ; YES, RESET FIRST BYTE PROPERLY. - LD A,(OLDDRV) ; AND GET THE OLD DRIVE AND SELECT IT. - LD (EPARAM),A - CALL SETDSK -GOBACK1:LD HL,(USRSTACK) ; RESET THE USERS STACK POINTER. - LD SP,HL - LD HL,(STATUS) ; GET RETURN STATUS. - LD A,L ; FORCE VERSION 1.4 COMPATABILITY. - LD B,H - RET ; AND GO BACK TO USER. -; -; FUNCTION #40. THIS IS A SPECIAL ENTRY TO DO RANDOM I/O. -; FOR THE CASE WHERE WE ARE WRITING TO UNUSED DISK SPACE, THIS -; SPACE WILL BE ZEROED OUT FIRST. THIS MUST BE A M/PM SPECIAL -; PURPOSE FUNCTION, BECAUSE WHY WOULD ANY NORMAL PROGRAM EVEN -; CARE ABOUT THE PREVIOUS CONTENTS OF A SECTOR ABOUT TO BE -; WRITTEN OVER. -; -WTSPECL:CALL AUTOSEL ; SELECT PROPER DRIVE. - LD A,2 ; USE SPECIAL WRITE MODE. - LD (MODE),A - LD C,0 ; SET WRITE INDICATOR. - CALL POSITN1 ; POSITION THE FILE. - CALL Z,WTSEQ1 ; AND WRITE (IF NO ERRORS). - RET -; -;************************************************************** -;* -;* BDOS DATA STORAGE POOL. -;* -;************************************************************** -; -EMPTYFCB: - .DB 0E5H ; EMPTY DIRECTORY SEGMENT INDICATOR. -WRTPRT: .DW 0 ; WRITE PROTECT STATUS FOR ALL 16 DRIVES. -LOGIN: .DW 0 ; DRIVE ACTIVE WORD (1 BIT PER DRIVE). -USERDMA:.DW 080H ; USER'S DMA ADDRESS (DEFAULTS TO 80H). -; -; SCRATCH AREAS FROM PARAMETER BLOCK. -; -SCRATCH1: - .DW 0 ; RELATIVE POSITION WITHIN DIR SEGMENT FOR FILE (0-3). -SCRATCH2: - .DW 0 ; LAST SELECTED TRACK NUMBER. -SCRATCH3: - .DW 0 ; LAST SELECTED SECTOR NUMBER. -; -; DISK STORAGE AREAS FROM PARAMETER BLOCK. -; -DIRBUF: .DW 0 ; ADDRESS OF DIRECTORY BUFFER TO USE. -DISKPB: .DW 0 ; CONTAINS ADDRESS OF DISK PARAMETER BLOCK. -CHKVECT:.DW 0 ; ADDRESS OF CHECK VECTOR. -ALOCVECT: - .DW 0 ; ADDRESS OF ALLOCATION VECTOR (BIT MAP). -; -; PARAMETER BLOCK RETURNED FROM THE BIOS. -; -SECTORS:.DW 0 ; SECTORS PER TRACK FROM BIOS. -BLKSHFT:.DB 0 ; BLOCK SHIFT. -BLKMASK:.DB 0 ; BLOCK MASK. -EXTMASK:.DB 0 ; EXTENT MASK. -DSKSIZE:.DW 0 ; DISK SIZE FROM BIOS (NUMBER OF BLOCKS-1). -DIRSIZE:.DW 0 ; DIRECTORY SIZE. -ALLOC0: .DW 0 ; STORAGE FOR FIRST BYTES OF BIT MAP (DIR SPACE USED). -ALLOC1: .DW 0 -OFFSET: .DW 0 ; FIRST USABLE TRACK NUMBER. -XLATE: .DW 0 ; SECTOR TRANSLATION TABLE ADDRESS. -; -; -CLOSEFLG: - .DB 0 ; CLOSE FLAG (=0FFH IS EXTENT WRITTEN OK). -R.DWRTFLG: - .DB 0 ; READ/WRITE FLAG (0FFH=READ, 0=WRITE). -FNDSTAT:.DB 0 ; FILENAME FOUND STATUS (0=FOUND FIRST ENTRY). -MODE: .DB 0 ; I/O MODE SELECT (0=RANDOM, 1=S.EQUENTIAL, 2=SPECIAL RANDOM). -EPARAM: .DB 0 ; STORAGE FOR REGISTER (E) ON ENTRY TO BDOS. -RELBLOCK: - .DB 0 ; RELATIVE POSITION WITHIN FCB OF BLOCK NUMBER WRITTEN. -COUNTER:.DB 0 ; BYTE COUNTER FOR DIRECTORY NAME SEARCHES. -SAVEFCB:.DW 0,0 ; SAVE SPACE FOR ADDRESS OF FCB (FOR DIRECTORY SEARCHES). -BIGDISK:.DB 0 ; IF =0 THEN DISK IS > 256 BLOCKS LONG. -AUTO: .DB 0 ; IF NON-ZERO, THEN AUTO SELECT ACTIVATED. -OLDDRV: .DB 0 ; ON AUTO SELECT, STORAGE FOR PREVIOUS DRIVE. -AUTOFLAG: - .DB 0 ; IF NON-ZERO, THEN AUTO SELECT CHANGED DRIVES. -SAVNXT: .DB 0 ; STORAGE FOR NEXT RECORD NUMBER TO ACCESS. -SAVEXT: .DB 0 ; STORAGE FOR EXTENT NUMBER OF FILE. -SAVNREC:.DW 0 ; STORAGE FOR NUMBER OF RECORDS IN FILE. -BLKNMBR:.DW 0 ; BLOCK NUMBER (PHYSICAL SECTOR) USED WITHIN A FILE OR LOGICAL SEC -LOGSECT:.DW 0 ; STARTING LOGICAL (128 BYTE) SECTOR OF BLOCK (PHYSICAL SECTOR). -FCBPOS: .DB 0 ; RELATIVE POSITION WITHIN BUFFER FOR FCB OF FILE OF INTEREST. -FILEPOS:.DW 0 ; FILES POSITION WITHIN DIRECTORY (0 TO MAX ENTRIES -1). -; -; DISK DIRECTORY BUFFER CHECKSUM BYTES. ONE FOR EACH OF THE -; 16 POSSIBLE DRIVES. -; -CKSUMTBL: - .DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -; -;************************************************************** -;* -;* B I O S J U M P T A B L E -;* -;************************************************************** -; - -BIOS: .EQU BIOSO ;BIOS ORIGIN -; -BOOT: .EQU BIOS ;(BOOT) Cold boot entry -WBOOT: .EQU BIOS+3 ;Warm boot entry -CONST: .EQU BIOS+6 ;Console status -CONIN: .EQU BIOS+9 ;Console char in -CONOUT: .EQU BIOS+12 ;Console char out -LIST: .EQU BIOS+15 ;List char out -PUNCH: .EQU BIOS+18 ;Punch char out -READER: .EQU BIOS+21 ;Reader char in -HOME: .EQU BIOS+24 ;Home disk -SELDSK: .EQU BIOS+27 ;Select disk -SETTRK: .EQU BIOS+30 ;Set disk track addr -SETSEC: .EQU BIOS+33 ;Set disk sector addr -SETDMA: .EQU BIOS+36 ;Set DMA buffer addr -READ: .EQU BIOS+39 ;Read sector -WRITE: .EQU BIOS+42 ;Write sector -SECTRN: .EQU BIOS+48 ;Sector translation routine -; - .IF ENDFIL - .ORG BDOSO+0DFFH - .DB 55H - .ENDIF - .END diff --git a/doug/ref/n8-romim.ref b/doug/ref/n8-romim.ref deleted file mode 100755 index 33dfdad8..00000000 Binary files a/doug/ref/n8-romim.ref and /dev/null differ diff --git a/doug/src/4th.s b/doug/src/4th.s deleted file mode 100755 index 728d7eca..00000000 --- a/doug/src/4th.s +++ /dev/null @@ -1,4310 +0,0 @@ -;------------------------------------------------------------------------------- -; Save to Space-Time Productions Z-80 directory on -; February 22, 2007 and converted terms for TASM -;------------------------------------------------------------------------------- -; -;------------------------------------------------------------------------------- -; This is an implementation of FORTH for the Z80 that should be easily portable -; to other Z80 systems. It assumes RAM from $9000 to $FFFF and a UART for -; communication with the host or VDU. -;------------------------------------------------------------------------------- -DATA_STACK: .EQU $FD80 ; Data stack grows down -VOCAB_BASE: .EQU $F000 ; Dictionary grows up from here -MASS_STORE: .EQU $FEA0 ; Mass storage buffer (default) -DISK_START: .EQU $A000 ; Pseudo disk buffer start -DISK_END: .EQU $F000 ; Pseudo disk buffer end -BLOCK_SIZE: .EQU $0200 ; Pseudo disk block size -BUFFERS: .EQU $0001 ; Pseudo disk buffers per block -MONSTART: .EQU $0000 ; Monitor entry address - -SYSTEM: .EQU $FE00 ; SYSTEM VARIABLES -S0: .EQU $FE06 ; Initial value of Data SP -R0: .EQU $FE08 ; Initial value of Return SP -TIB: .EQU $FE0A ; Terminal Input Buffer -WIDTH: .EQU $FE0C ; Number of letters saved in names -WARNING: .EQU $FE0E ; Error message control number -FENCE: .EQU $FE10 ; Dictionary FORGET -DP: .EQU $FE12 ; Dictionary Pointer -VOC_LINK: .EQU $FE14 ; Most recently created vocabulary -BLK: .EQU $FE16 ; Current block number interpretation -TOIN: .EQU $FE18 ; Offset in the current input text buffer -OUT: .EQU $FE1A ; Offset in the current output text buff -SCR: .EQU $FE1C ; Screen number last ref'd by LIST -OFFSET: .EQU $FE1E ; Block offset for disk drives -CONTEXT: .EQU $FE20 ; Pointer to vocabulary within which - ; dictionary search will first begin -CURRENT: .EQU $FE22 ; Pointer to the vocabulary within which - ; new definitions are to be created -STATE: .EQU $FE24 ; Contains state of compilation -BASE: .EQU $FE26 ; Current I/O Base Address -DPL: .EQU $FE28 ; Number of digits to the right of the - ; decimal point on double integer input -FLD: .EQU $FE2A ; Field width for formatted number output -CSP: .EQU $FE2C ; Check SP -RHASH: .EQU $FE2E ; Location of editor cursor in a txt blk -HLD: .EQU $FE30 ; Address of current output -FLAST: .EQU $FE32 ; FORTH vocabulary data initialized -ELAST: .EQU $FE38 ; Editor vocabulary data -CRFLAG: .EQU $FE3E ; Carriage Return flag -PAT: .EQU $FE40 ; I/O port fetch routine INPUT -PST: .EQU $FE43 ; I/O port store routine OUTPUT -RPP: .EQU $FE46 ; Return SP -USE: .EQU $FE48 ; Mass storage buffer address to use -PREV: .EQU $FE4A ; Mass storage buffer address just used -INTFLAG: .EQU $FE4C ; Interrupt flag and user byte following -INTVECT: .EQU $FE4E ; Interrupt vector -UTERMNL: .EQU $FE50 ; Code field address of word ?TERMINAL -UKEY: .EQU $FE52 ; Code field address of word KEY -UEMIT: .EQU $FE54 ; Code field address of word EMIT -UCR: .EQU $FE56 ; Code field address of word CR -URW: .EQU $FE58 ; Code field address of word R/W -UABORT: .EQU $FE5A ; Code field address of word ABORT -UCL: .EQU $FE5C ; Number of chars per input line -UFIRST: .EQU $FE5E ; Start of pseudo disk buffer -ULIMIT: .EQU $FE60 ; End of pseudo disk buffer -UBBUF: .EQU $FE62 ; Number of bytes per block -UBSCR: .EQU $FE64 ; Number of buffers per block -KEYBUF: .EQU $FE66 ; Double key buffer -RAF: .EQU $FE68 ; Register AF -RBC: .EQU $FE6A ; Register BC -RDE: .EQU $FE6C ; Register DE -RHL: .EQU $FE6E ; Register HL -RIX: .EQU $FE70 ; Register IX -RIY: .EQU $FE72 ; Register IY -RAF2: .EQU $FE74 ; Register AF' -RBC2: .EQU $FE76 ; Register BC' -RDE2: .EQU $FE78 ; Register DE' -RHL2: .EQU $FE7A ; Regisetr HL' -JPCODE: .EQU $FE7D ; JP code ($C3) for word -JPVECT: .EQU $FE7E ; JP vector -;------------------------------------------------------------------------------ -FORTH: .ORG $8000 ; Start of RAM - - XOR A ; Clear A - LD (KEYBUF),A ; Clear buffered key - JP X_COLD - -BACKSPACE: - .WORD $0008 ; Backspace chr - -WORD1: .WORD DATA_STACK -DEF_SYSADDR: - .WORD SYSTEM - .WORD DATA_STACK - .WORD $001F ; Word name length (default 31) - .WORD $0000 ; Error message control number - .WORD VOCAB_BASE ; FORGET protection - .WORD VOCAB_BASE+$0B ; Dictionary pointer - .WORD E_FORTH ; Most recently created vocab. - -START_TABLE: - .BYTE $81,$A0 - .WORD VOCAB_BASE - .BYTE $00,$00 ; FLAST - .BYTE $81,$A0 - .WORD W_EDITI - .WORD E_FORTH ; ELAST - .BYTE $00 ; CRFLAG - .BYTE $00 ; Free - IN A,($00) ; I/O Port input - RET ; routine - OUT ($00),A ; I/O Port output - RET ; routine - .WORD SYSTEM ; Return stack pointer - .WORD MASS_STORE ; Mass storage buffer to use - .WORD MASS_STORE ; Storage buffer just used - .BYTE $00 ; Interrupt flag - .BYTE $00 ; Free - .WORD C_ABORT ; Interrupt vector - .WORD CF_UQTERMINAL ; C field address ?TERMINAL - .WORD CF_UKEY ; C field address KEY - .WORD CF_UEMIT ; C field address EMIT - .WORD CF_UCR ; C field address CR - .WORD CF_URW ; C field address R/W - .WORD CF_UABORT ; C field address ABORT - .WORD $0020 ; CHRs per input line - .WORD DISK_START ; Pseudo disk buf start - .WORD DISK_END ; Pseudo disk buf end - .WORD BLOCK_SIZE ; Bytes per block - .WORD BUFFERS ; Buffers per block - -NEXTS2: PUSH DE -NEXTS1: PUSH HL -NEXT: LD A,(INTFLAG) ; Interrupt flag - BIT 7,A ; Check for interrupt - JR Z,NOINT ; No interrupt - BIT 6,A ; Interrupt enabled ? - JR NZ,NOINT ; No interrupt - LD HL,(INTVECT) ; Get nterrupt vector - LD A,$40 ; Clear flag byte - LD (INTFLAG),A ; Interrupt flag into HL - JR NEXTADDR ; JP (HL) - -NOINT: LD A,(BC) ; effectively LD HL,(BC) - INC BC ; - LD L,A ; - LD A,(BC) ; - INC BC ; BC now points to next vector - LD H,A ; HL has addr vector - -NEXTADDR: LD E,(HL) ; effectively LD HL,(HL) - INC HL ; - LD D,(HL) ; - EX DE,HL ; - JP (HL) ; Jump to it - -W_LIT: ; Puts next 2 bytes on the stack - .BYTE $83,"LI",'T'+$80 - .WORD $0000 ; First word in vocabulary -C_LIT: .WORD 2+$ ; Vector to code - LD A,(BC) ; Gets next word from (BC) - INC BC ; then increments BC to point - LD L,A ; to the next addr. Pushes the - LD A,(BC) ; result onto the stack. - INC BC ; - LD H,A ; - JP NEXTS1 ; Save & NEXT - - -W_EXECUTE: ; Jump to address on stack - .BYTE $87,"EXECUT",'E'+$80 - .WORD W_LIT -C_EXECUTE: - .WORD 2+$ ; Vector to code - POP HL ; Get addr off data stack - JP NEXTADDR ; Basically JP (HL) - - -W_BRANCH: ; Add following offset to BC - .BYTE $86,"BRANC",'H'+$80 - .WORD W_EXECUTE -C_BRANCH: .WORD 2+$ ; Vector to code -X_BRANCH: LD H,B ; Next pointer into HL - LD L,C ; - LD E,(HL) ; Get word offset LD DE,(HL) - INC HL ; Incr to point at next byte - LD D,(HL) ; - DEC HL ; Restore HL - ADD HL,DE ; Calculate new address - LD C,L ; Put it in BC - LD B,H ; - JP NEXT ; Go do it - - -W_0BRANCH: ; Add offset to BC if stack top = 0 - .BYTE $87,"0BRANC",'H'+$80 ; Conditional branch - .WORD W_BRANCH -C_0BRANCH: - .WORD 2+$ ; Vector to code - POP HL ; Get value off stack - LD A,L ; Set flags - OR H ; - JR Z,X_BRANCH ; If zero then do the branch - INC BC ; Else dump branch address - INC BC ; - JP NEXT ; Continue execution - -W_LLOOP: ; Increment loop & branch if not done - .BYTE $86,"'+$80 - .WORD W_0BRANCH -C_LLOOP: - .WORD 2+$ ; Vector to code - LD DE,0001 -C_ILOOP: - LD HL,(RPP) ; Get return stack pointer - LD A,(HL) ; Add DE to value on return stack - ADD A,E ; - LD (HL),A ; - LD E,A ; - INC HL ; - LD A,(HL) ; - ADC A,D ; - LD (HL),A ; - INC HL ; HL now points to limit value - INC D ; Get Ds sign bit - DEC D ; - LD D,A ; Result now in DE - JP M,DECR_LOOP ; Decrement loop so check > limit - ; otherwies check < limit - LD A,E ; Low byte back - SUB (HL) ; Subtract limit low - LD A,D ; High byte back - INC HL ; Point to limit high - SBC A,(HL) ; Subtract it - JR TEST_LIMIT ; -DECR_LOOP: - LD A,(HL) ; Get limit low - SUB E ; Subtract index low - INC HL ; Point to limit high - LD A,(HL) ; Get it - SBC A,D ; Subtract index high -TEST_LIMIT: - JP M,X_BRANCH ; Not reached limit so jump - INC HL ; Drop index & limit from return stack - LD (RPP),HL ; Save stack pointer - INC BC ; Skip branch offset - INC BC ; - JP NEXT - -W_PLOOP: ; Loop + stack & branch if not done - .BYTE $87,"<+LOOP",'>'+$80 - .WORD W_LLOOP -C_PLOOP: - .WORD 2+$ ; Vector to code - POP DE ; Get value from stack - JR C_ILOOP ; Go do loop increment - -W_LDO: ; Put start & end loop values on RPP - .BYTE $84,"'+$80 - .WORD W_PLOOP -C_LDO: - .WORD 2+$ - LD HL,(RPP) ; Get return stack pointer - DEC HL ; Add space for two values - DEC HL ; - DEC HL ; - DEC HL ; - LD (RPP),HL ; Save new stack pointer - POP DE ; Get start value & - LD (HL),E ; put on return stack top - INC HL ; - LD (HL),D ; - INC HL ; - POP DE ; Get end value & - LD (HL),E ; put on return stack - 1 - INC HL ; - LD (HL),D ; - JP NEXT - -W_I: ; Copy LOOP index to data stack - .BYTE $81,'I'+$80 - .WORD W_LDO -C_I: - .WORD 2+$ -X_I: - LD HL,(RPP) ; Get return stack pointer -X_I2: - LD E,(HL) ; Get LOOP index off return stack - INC HL ; - LD D,(HL) ; - PUSH DE ; Push onto data stack - JP NEXT - -W_DIGIT: ; Convert digit n2 using base n1 - .BYTE $85,"DIGI",'T'+$80 - .WORD W_I -C_DIGIT: - .WORD 2+$ - POP HL ; Get base to use - POP DE ; Get char - LD A,E ; A = char - SUB $30 ; Subtract 30h - JP M,NDIGIT - CP $0A ; Greater than 9 ? - JP M,LESS10 ; If not then skip - SUB $07 ; Convert 'A' to 10 - CP $0A ; Is it 10? - JP M,NDIGIT ; If not an error occured -LESS10: - CP L ; L is 1 digit limit - JP P,NDIGIT ; Out of range for digit - LD E,A ; Result into DE - LD HL,0001 ; Leave TRUE flag - JP NEXTS2 ; Save both & NEXT -NDIGIT: - LD L,H ; Leave FALSE flag - JP NEXTS1 ; Save & NEXT - -W_FIND: ; Find word & return vector,byte & flag - .BYTE $86,"'+$80 - .WORD W_DIGIT -C_FIND: - .WORD 2+$ ; Vector to code - POP DE ; Get pointer to next vocabulary word -COMPARE: - POP HL ; Copy pointer to word we're looking 4 - PUSH HL ; - LD A,(DE) ; Get 1st vocabulary word letter - XOR (HL) ; Compare with what we've got - AND $3F ; Ignore start flag - JR NZ,NOT_END_CHR ; No match so skip to next word -MATCH_NO_END: - INC HL ; Compare next chr - INC DE ; - LD A,(DE) ; - XOR (HL) ; - ADD A,A ; Move bit 7 to C flag - JR NZ,NO_MATCH ; No match jump - JR NC,MATCH_NO_END ; Match & not last, so next chr - LD HL,0005 ; Offset to start of code - ADD HL,DE ; HL now points to code start for word - EX (SP),HL ; Swap with value on stack -NOT_WORD_BYTE: - DEC DE ; Search back for word type byte - LD A,(DE) ; - OR A ; - JP P,NOT_WORD_BYTE ; Not yet so loop - LD E,A ; Byte into DE - LD D,$00 ; - LD HL,0001 ; Leave TRUE flag - JP NEXTS2 ; Save both & NEXT -NO_MATCH: - JR C,END_CHR ; If last chr then jump -NOT_END_CHR: - INC DE ; Next chr of this vocab word - LD A,(DE) ; Get it - OR A ; Set flags - JP P,NOT_END_CHR ; Loop if not end chr -END_CHR: - INC DE ; Now points to next word vector - EX DE,HL ; Swap - LD E,(HL) ; Vector into DE - INC HL ; - LD D,(HL) ; - LD A,D ; Check it's not last (first) word - OR E ; - JR NZ,COMPARE ; No error so loop - POP HL ; Dump pointer - LD HL,0000 ; Flag error - JP NEXTS1 ; Save & NEXT - -W_ENCLOSE: - .BYTE $87,"ENCLOS",'E'+$80 - .WORD W_FIND -C_ENCLOSE: - .WORD 2+$ ; Vector to code - POP DE ; get delimiter character - POP HL ; get address 1 - PUSH HL ; duplicate it - LD A,E ; delimiter char into A - LD D,A ; copy to D - LD E,$ff ;-1 for offset - DEC HL ; to allow for first INCR -J21E6: - INC HL ; point to next chr - INC E ; next offset - CP (HL) ; compare chr with (address) - JR Z,J21E6 ; loop if = delimiter chr - LD A,$0D ; else set CR - CP (HL) ; compare with (address) - LD A,D ; restore delimiter chr - JR Z,J21E6 ; loop if it was = CR - LD D,$00 ; zero high byte - PUSH DE ; save offset - LD D,A ; restore delimiter chr - LD A,(HL) ; get byte from address - AND A ; set the flags - JR NZ,J2202 ; branch if not null - LD D,$00 ; clear high byte - INC E ; point to next addr - PUSH DE ; save address - DEC E ; point to end - PUSH DE ; push address - JP NEXT ; done -J2202: - LD A,D ; restore delimiter chr - INC HL ; increment address - INC E ; increment offset - CP (HL) ; compare delimiter with (address) - JR Z,J2218 ; jump if = - LD A,$0D ; else get CR - CP (HL) ; compare with (address) - JR Z,J2218 ; jump if = - LD A,(HL) ; else get byte - AND A ; set the flags - JR NZ,J2202 ; loop if not null - LD D,$00 ; clear gigh byte - PUSH DE ; save address - PUSH DE ; save address - JP NEXT ; done -J2218: - LD D,$00 ; clear high byte - PUSH DE ; save address - INC E ; increment offset - PUSH DE ; save address - JP NEXT ; done - -W_EMIT: ; Output CHR from stack - .BYTE $84,"EMI",'T'+$80 - .WORD W_ENCLOSE -C_EMIT: - .WORD E_COLON ; Interpret following word sequence - .WORD C_UEMIT ; Put UEMIT addr on stack - .WORD C_FETCH ; Get UEMIT code field address - .WORD C_EXECUTE ; Jump to address on stack - .WORD C_1 - .WORD C_OUT - .WORD C_PLUSSTORE - .WORD C_STOP ; Pop BC from return stack (=next) - -W_KEY: ; Wait for key, value on stack - .BYTE $83,"KE",'Y'+$80 - .WORD W_EMIT -C_KEY: - .WORD 2+$ ; Vector to code - LD HL,(UKEY) ; Get the vector - JP (HL) ; Jump to it - -; .WORD E_COLON ; Interpret following word sequence -; .WORD C_UKEY ; Put UKEY addr on stack -; .WORD C_FETCH ; Get CF_KEY -; .WORD C_EXECUTE ; Jump to CF_KEY -; .WORD C_STOP ; Pop BC from return stack (=next) - - -W_TERMINAL: - .BYTE $89,"?TERMINA",'L'+$80 - .WORD W_KEY -C_TERMINAL: - .WORD E_COLON ; Interpret following word sequence - .WORD C_UTERMINAL - .WORD C_FETCH ; Get word from addr on stack - .WORD C_EXECUTE ; Jump to address on stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_CR: ; Output [CR][LF] - .BYTE $82,"C",'R'+$80 - .WORD W_TERMINAL -C_CR: - .WORD E_COLON ; Interpret following word sequence - .WORD C_UCR ; Push UCR addr - .WORD C_FETCH ; Get UCR code field addr - .WORD C_EXECUTE ; Jump to address on stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_CLS: ; Clear screen - .BYTE $83,"CL",'S'+$80 - .WORD W_CR -C_CLS: - .WORD E_COLON ; Interpret following word sequence - .WORD C_LIT ; Put clear screen code on stack - .WORD 000Ch ; - .WORD C_EMIT ; Output it - .WORD C_STOP ; Pop BC from return stack (=next) - -W_CMOVE: ; Move block - .BYTE $85,"CMOV",'E'+$80 - .WORD W_CLS -C_CMOVE: - .WORD 2+$ ; Vector to code - LD L,C ; Save BC for now - LD H,B ; - POP BC ; Get no. of bytes to move - POP DE ; Get destination address - EX (SP),HL ; Get source address - LD A,B ; Check it's not a 0 length block - OR C ; - JR Z,NO_BYTES ; If 0 length then do nothing - LDIR ; Move block -NO_BYTES: - POP BC ; Get BC back - JP NEXT - -W_USTAR: ; Unsigned multiply - .BYTE $82,"U",'*'+$80 - .WORD W_CMOVE -C_USTAR: - .WORD 2+$ ; Vector to code - POP DE ; get n2 - POP HL ; get n1 - PUSH BC ; save BC for now - LD C,H ; save H - LD A,L ; low byte to multiply by - CALL HALF_TIMES ; HL = A * DE - PUSH HL ; save partial result - LD H,A ; clear H - LD A,C ; high byte to multiply by - LD C,H ; clear B - CALL HALF_TIMES ; HL = A * DE - POP DE ; get last partial result - LD B,C ; add partial results - LD C,D ; add partial results - ADD HL,BC ; - ADC A,$00 ; - LD D,L ; - LD L,H ; - LD H,A ; - POP BC ; get BC back - JP NEXTS2 ; save 32 bit result & NEXT - -HALF_TIMES: ; - LD HL,$0000 ; clear partial result - LD B,08h ; eight bits to do -NEXT_BIT: - ADD HL,HL ; result * 2 - RLA ; multiply bit into C - JR NC,NO_MUL ; branch if no multiply - ADD HL,DE ; add multiplicand - ADC A,$00 ; add in any carry -NO_MUL: - DJNZ NEXT_BIT ; decr and loop if not done - RET ; - -W_UMOD: ; Unsigned divide & MOD - .BYTE $85,"U/MO",'D'+$80 - .WORD W_USTAR -C_UMOD: - .WORD 2+$ ; Vector to code - LD HL,0004 - ADD HL,SP - LD E,(HL) - LD (HL),C - INC HL - LD D,(HL) - LD (HL),B - POP BC - POP HL - LD A,L - SUB C - LD A,H - SBC A,B - JR C,J22DB - LD HL,$FFFF - LD DE,$FFFF - JR J2301 -J22DB: - LD A,10h -J22DD: - ADD HL,HL - RLA - EX DE,HL - ADD HL,HL - JR NC,J22E5 - INC DE - AND A -J22E5: - EX DE,HL - RRA - PUSH AF - JR NC,J22F2 - LD A,L - SUB C - LD L,A - LD A,H - SBC A,B - LD H,A - JR J22FC -J22F2: - LD A,L - SUB C - LD L,A - LD A,H - SBC A,B - LD H,A - JR NC,J22FC - ADD HL,BC - DEC DE -J22FC: - INC DE - POP AF - DEC A - JR NZ,J22DD -J2301: - POP BC - PUSH HL - PUSH DE - JP NEXT - -W_AND: ; AND - .BYTE $83,"AN",'D'+$80 - .WORD W_UMOD -C_AND: - .WORD 2+$ ; Vector to code - POP DE ; Get n1 off stack - POP HL ; Get n2 off stack - LD A,E ; AND lo bytes - AND L ; - LD L,A ; Result in L - LD A,D ; AND hi bytes - AND H ; - LD H,A ; Result in H - JP NEXTS1 ; Save & next - -W_OR: ; OR - .BYTE $82,"O",'R'+$80 - .WORD W_AND -C_OR: - .WORD 2+$ ; Vector to code - POP DE ; Get n1 off stack - POP HL ; Get n2 off stack - LD A,E ; OR lo bytes - OR L ; - LD L,A ; Result in L - LD A,D ; OR hi bytes - OR H ; - LD H,A ; Result in H - JP NEXTS1 ; Save & next - -W_XOR: ; XOR - .BYTE $83,"XO",'R'+$80 - .WORD W_OR -C_XOR: - .WORD 2+$ ; Vector to code - POP DE ; Get n1 off stack - POP HL ; Get n2 off stack - LD A,E ; XOR lo bytes - XOR L ; - LD L,A ; Result in L - LD A,D ; XOR hi bytes - XOR H ; - LD H,A ; Result in H - JP NEXTS1 ; Save & NEXT - -W_SPFETCH: ; Stack pointer onto stack - .BYTE $83,"SP",'@'+$80 - .WORD W_XOR -C_SPFETCH: - .WORD 2+$ ; Vector to code - LD HL,0000 ; No offset - ADD HL,SP ; Add SP to HL - JP NEXTS1 ; Save & NEXT - -W_SPSTORE: ; Set initial stack pointer value - .BYTE $83,"SP",'!'+$80 - .WORD W_SPFETCH -C_SPSTORE: - .WORD 2+$ ; Vector to code - LD HL,(DEF_SYSADDR) ; Get system base addr - LD DE,S0-SYSTEM ; Offset to stack pointer value (0006) - ADD HL,DE ; Add to base addr - LD E,(HL) ; Get SP from ram - INC HL ; - LD D,(HL) ; - EX DE,HL ; Put into HL - LD SP,HL ; Set SP - JP NEXT - -W_RPFETCH: ; Get return stack pointer - .BYTE $83,"RP",'@'+$80 - .WORD W_SPSTORE -C_RPFETCH: - .WORD 2+$ ; Vector to code - LD HL,(RPP) ; Return stack pointer into HL - JP NEXTS1 ; Save & NEXT - -W_RPSTORE: ; Set initial return stack pointer - .BYTE $83,"RP",'!'+$80 - .WORD W_RPFETCH -C_RPSTORE: - .WORD 2+$ ; Vector to code - LD HL,(DEF_SYSADDR) ; Get system base addr - LD DE,0008 ; Offset to return stack pointer value - ADD HL,DE ; Add to base addr - LD E,(HL) ; Get SP from ram - INC HL ; - LD D,(HL) ; - EX DE,HL ; Put into HL - LD (RPP),HL ; Set return SP - JP NEXT - -W_STOP: ; Pop BC from return stack (=next) - .BYTE $82,"; ",'S'+$80 - .WORD W_RPSTORE -C_STOP: - .WORD 2+$ ; Vector to code -X_STOP: - LD HL,(RPP) ; Return stack pointer to HL - LD C,(HL) ; Get low byte - INC HL ; - LD B,(HL) ; Get high byte - INC HL ; - LD (RPP),HL ; Save stack pointer - JP NEXT - -W_LEAVE: ; Quit loop by making index = limit - .BYTE $85,"LEAV",'E'+$80 - .WORD W_STOP -C_LEAVE: - .WORD 2+$ ; Vector to code - LD HL,(RPP) ; Get return stack pointer - LD E,(HL) ; Get loop limit low - INC HL ; - LD D,(HL) ; Get loop limit high - INC HL ; - LD (HL),E ; Set index low to loop limit - INC HL ; - LD (HL),D ; Set index high to loop limit - JP NEXT - -W_MOVER: ; Move from data to return stack - .BYTE $82,">",'R'+$80 - .WORD W_LEAVE -C_MOVER: - .WORD 2+$ ; Vector to code - POP DE ; Get value - LD HL,(RPP) ; Get return stack pointer - DEC HL ; Set new value - DEC HL ; - LD (RPP),HL ; Save it - LD (HL),E ; Push low byte onto return stack - INC HL ; - LD (HL),D ; Push high byte onto return stack - JP NEXT - -W_RMOVE: ; Move word from return to data stack - .BYTE $82,"R",'>'+$80 - .WORD W_MOVER -C_RMOVE: - .WORD 2+$ ; Vector to code - LD HL,(RPP) ; Get return stack pointer - LD E,(HL) ; Pop word off return stack - INC HL ; - LD D,(HL) ; - INC HL ; - LD (RPP),HL ; Save new return stack pointer - PUSH DE ; Push on data stack - JP NEXT - -W_RFETCH: ; Return stack top to data stack - .BYTE $82,"R",'@'+$80 - .WORD W_RMOVE -C_RFETCH: - .WORD X_I ; Return stack top to data stack - - -W_0EQUALS: ; =0 - .BYTE $82,"0",'='+$80 - .WORD W_RFETCH -C_0EQUALS: - .WORD 2+$ ; Vector to code -X_0EQUALS: - POP HL ; Get value from stack - LD A,L ; set flags - OR H ; - LD HL,0000 ; Not = 0 flag - JR NZ,NO_ZERO ; - INC HL ; = 0 flag -NO_ZERO: - JP NEXTS1 ; Save & NEXT - -W_NOT: ; Convert flag, same as 0= - .BYTE $83,"NO",'T'+$80 - .WORD W_0EQUALS -C_NOT: - .WORD X_0EQUALS - -W_0LESS: ; Less than 0 - .BYTE $82,"0",'<'+$80 - .WORD W_NOT -C_0LESS: - .WORD 2+$ ; Vector to code - POP HL ; Get value - ADD HL,HL ; S bit into C - LD HL,0000 ; Wasn't < 0 flag - JR NC,NOT_LT0 ; - INC HL ; Was < 0 flag -NOT_LT0: JP NEXTS1 ; Save & NEXT - -W_PLUS: ; n1 + n2 - .BYTE $81,'+'+$80 - .WORD W_0LESS -C_PLUS: - .WORD 2+$ ; Vector to code - POP DE ; Get n2 - POP HL ; Get n1 - ADD HL,DE ; Add them - JP NEXTS1 ; Save & NEXT - -W_DPLUS: ; 32 bit add - .BYTE $82,"D",'+'+$80 - .WORD W_PLUS -C_DPLUS: - .WORD 2+$ ; Vector to code - LD HL,0006 ; offset to low word - ADD HL,SP ; add stack pointer - LD E,(HL) ; get d1 low word low byte - LD (HL),C ; save BC low byte - INC HL ; point to high byte - LD D,(HL) ; get d1 low word high byte - LD (HL),B ; save BC high byte - POP BC ; get high word d2 - POP HL ; get low word d2 - ADD HL,DE ; add low words - EX DE,HL ; save result low word in DE - POP HL ; get d1 high word - LD A,L ; copy d1 high word low byte - ADC A,C ; add d2 high word low byte - ; + carry from low word add - LD L,A ; result from high word low byte into L - LD A,H ; copy d1 high word low byte - ADC A,B ; add d2 high word low byte - ; + carry from high word low byte add - LD H,A ; result from high word high byte into H - POP BC ; restore BC - JP NEXTS2 ; Save 32 bit result & NEXT - -W_NEGATE: ; Form 2s complement of n - .BYTE $86,"NEGAT",'E'+$80 - .WORD W_DPLUS -C_NEGATE: - .WORD 2+$ ; Vector to code - POP HL ; Get number - LD A,L ; Low byte into A - CPL ; Complement it - LD L,A ; Back into L - LD A,H ; High byte into A - CPL ; Complement it - LD H,A ; Back into H - INC HL ; +1 - JP NEXTS1 ; Save & NEXT - -W_DNEGATE: ; Form 2s complement of 32 bit n - .BYTE $87,"DNEGAT",'E'+$80 - .WORD W_NEGATE -C_DNEGATE: - .WORD 2+$ ; Vector to code - POP HL ; get high word - POP DE ; get low word - SUB A ; clear A - SUB E ; negate low word low byte - LD E,A ; copy back to E - LD A,$00 ; clear A - SBC A,D ; negate low word high byte - LD D,A ; copy back to D - LD A,$00 ; clear A - SBC A,L ; negate high word low byte - LD L,A ; copy back to L - LD A,$00 ; clear A - SBC A,H ; negate high word high byte - LD H,A ; copy back to H - JP NEXTS2 ; Save 32 bit result & NEXT - -W_OVER: ; Copy 2nd down to top of stack - .BYTE $84,"OVE",'R'+$80 - .WORD W_DNEGATE -C_OVER: - .WORD 2+$ ; Vector to code - POP DE ; Get top - POP HL ; Get next - PUSH HL ; Save it back - JP NEXTS2 ; Save both & NEXT - -W_DROP: ; Drop top value from stack - .BYTE $84,"DRO",'P'+$80 - .WORD W_OVER -C_DROP: - .WORD 2+$ ; Vector to code - POP HL ; Get top value - JP NEXT - -W_2DROP: ; Drop top two values from stack - .BYTE $85,"2DRO",'P'+$80 - .WORD W_DROP -C_2DROP: - .WORD 2+$ ; Vector to code - POP HL ; Get top value - POP HL ; Get top value - JP NEXT - -W_SWAP: ; Swap top 2 values on stack - .BYTE $84,"SWA",'P'+$80 - .WORD W_2DROP -C_SWAP: - .WORD 2+$ ; Vector to code - POP HL ; Get top value - EX (SP),HL ; Exchanhe with next down - JP NEXTS1 ; Save & NEXT - -W_DUP: ; Duplicate top value on stack - .BYTE $83,"DU",'P'+$80 - .WORD W_SWAP -C_DUP: - .WORD 2+$ ; Vector to code - POP HL ; Get value off stack - PUSH HL ; Copy it back - JP NEXTS1 ; Save & NEXT - -W_2DUP: ; Dup top 2 values on stack - .BYTE $84,"2DU",'P'+$80 - .WORD W_DUP -C_2DUP: - .WORD 2+$ ; Vector to code - POP HL ; Get top two values from stack - POP DE ; - PUSH DE ; Copy them back - PUSH HL ; - JP NEXTS2 ; Save both & NEXT - -W_BOUNDS: ; Convert address & n to start & end - .BYTE $86,"BOUND",'S'+$80 - .WORD W_2DUP -C_BOUNDS: - .WORD 2+$ ; Vector to code - POP HL ; get n - POP DE ; get addr - ADD HL,DE ; add addr to n - EX DE,HL ; swap them - JP NEXTS2 ; save both & NEXT - -W_PLUSSTORE: ; Add n1 to addr - .BYTE $82,"+",'!'+$80 - .WORD W_BOUNDS -C_PLUSSTORE: - .WORD 2+$ ; Vector to code - POP HL ; Get addr - POP DE ; Get DE - LD A,(HL) ; Add low bytes - ADD A,E ; - LD (HL),A ; Store result - INC HL ; Point to high byte - LD A,(HL) ; Add high bytes - ADC A,D ; - LD (HL),A ; Store result - JP NEXT - -W_TOGGLE: ; XOR (addr) with byte - .BYTE $86,"TOGGL",'E'+$80 - .WORD W_PLUSSTORE -C_TOGGLE: - .WORD 2+$ ; Vector to code - POP DE ; Get byte - POP HL ; Get addr - LD A,(HL) ; Get byte from addr - XOR E ; Toggle it - LD (HL),A ; Save result - JP NEXT - -W_FETCH: ; Get word from addr on stack - .BYTE $81,'@'+$80 - .WORD W_TOGGLE -C_FETCH: - .WORD 2+$ ; Vector to code - POP HL ; Get addr - LD E,(HL) ; Get low byte - INC HL ; - LD D,(HL) ; Get high byte - PUSH DE ; Save it - JP NEXT - -W_CFETCH: ; Get byte from addr on stack - .BYTE $82,"C",'@'+$80 - .WORD W_FETCH -C_CFETCH: - .WORD 2+$ ; Vector to code - POP HL ; Get addr - LD L,(HL) ; Get byte - LD H,$00 ; Top byte = 0 - JP NEXTS1 ; Save & NEXT - -W_2FETCH: ; Get word from addr+2 and addr - .BYTE $82,"2",'@'+$80 - .WORD W_CFETCH -C_2FETCH: - .WORD 2+$ ; Vector to code - POP HL ; Get addr - LD DE,0002 ; Plus 2 bytes - ADD HL,DE ; Get 2nd word first - LD E,(HL) ; Low byte - INC HL ; - LD D,(HL) ; High byte - PUSH DE ; Save it - LD DE,$FFFD ; Minus 2 bytes - ADD HL,DE ; Get 1st word - LD E,(HL) ; Low byte - INC HL ; - LD D,(HL) ; High byte - PUSH DE ; Save it - JP NEXT - -W_STORE: ; Store word at addr - .BYTE $81,'!'+$80 - .WORD W_2FETCH -C_STORE: - .WORD 2+$ ; Vector to code - POP HL ; Get addr - POP DE ; Get word - LD (HL),E ; Store low byte - INC HL ; - LD (HL),D ; Store high byte - JP NEXT - -W_CSTORE: ; Store byte at addr - .BYTE $82,"C",'!'+$80 - .WORD W_STORE -C_CSTORE: - .WORD 2+$ ; Vector to code - POP HL ; Get addr - POP DE ; Get byte - LD (HL),E ; Save it - JP NEXT - -W_2STORE: ; Store 2 words at addr (+2) - .BYTE $82,"2",'!'+$80 - .WORD W_CSTORE -C_2STORE: - .WORD 2+$ ; Vector to code - POP HL ; Get addr - POP DE ; Get word - LD (HL),E ; Save low byte - INC HL ; - LD (HL),D ; Save high byte - INC HL ; - POP DE ; Get next word - LD (HL),E ; Save low byte - INC HL ; - LD (HL),D ; Save high byte - JP NEXT - -W_COLON: - .BYTE $81,':'+$80 - .WORD W_2STORE -C_COLON: - .WORD E_COLON ; Interpret following word sequence - .WORD C_QEXEC ; Error not if not in execute mode - .WORD C_CSPSTORE ; Set current stack pointer value - .WORD C_CURRENT ; Get CURRENT addr - .WORD C_FETCH ; Get word from addr on stack - .WORD C_CONTEXT ; Make CONTEXT current vocab - .WORD C_STORE ; Store word at addr - .WORD C_XXX1 ; Puts name into dictionary - .WORD C_RIGHTBRKT ; Set STATE to compile - .WORD C_CCODE ; Execute following machine code - -E_COLON: - LD HL,(RPP) ; Get return stack pointer - DEC HL ; Put BC on return stack - LD (HL),B ; - DEC HL ; - LD (HL),C ; - LD (RPP),HL ; Save new pointer - INC DE - LD C,E - LD B,D - JP NEXT - -W_SEMICOLON: ; Terminate compilation - .BYTE $C1,'; '+$80 - .WORD W_COLON -C_SEMICOLON: - .WORD E_COLON ; Interpret following word sequence - .WORD C_QCOMP ; Check we're allready compiling - .WORD C_WHATSTACK ; Check stack pointer, error if not ok - .WORD C_COMPILE ; Compile next word into dictionary - .WORD C_STOP ; - .WORD C_SMUDGE ; Smudge bit to O.K. - .WORD C_LEFTBRKT ; Set STATE to execute - .WORD C_STOP ; Pop BC from return stack (=next) - -W_CONSTANT: - .BYTE $88,"CONSTAN",'T'+$80 - .WORD W_SEMICOLON -C_CONSTANT: - .WORD E_COLON ; Interpret following word sequence - .WORD C_XXX1 - .WORD C_SMUDGE - .WORD C_COMMA ; Reserve 2 bytes and save n - .WORD C_CCODE ; Execute following machine code - -X_CONSTANT: ; Put next word on stack - INC DE ; Adjust pointer - EX DE,HL ; Get next word - LD E,(HL) ; - INC HL ; - LD D,(HL) ; - PUSH DE ; Put on stack - JP NEXT - -W_VARIABLE: - .BYTE $88,"VARIABL",'E'+$80 - .WORD W_CONSTANT -C_VARIABLE: - .WORD E_COLON ; Interpret following word sequence - .WORD C_ZERO ; Put zero on stack - .WORD C_CONSTANT - .WORD C_CCODE ; Execute following machine code - -X_VARIABLE: - INC DE - PUSH DE - JP NEXT - -W_USER: - .BYTE $84,"USE",'R'+$80 - .WORD W_VARIABLE -C_USER: - .WORD E_COLON ; Interpret following word sequence - .WORD C_CONSTANT - .WORD C_CCODE ; Execute following machine code - -X_USER: - INC DE ; Adjust to next word - EX DE,HL - LD E,(HL) - INC HL - LD D,(HL) - LD HL,(DEF_SYSADDR) - ADD HL,DE - JP NEXTS1 ; Save & NEXT - -W_ZERO: ; Put zero on stack - .BYTE $81,'0'+$80 - .WORD W_USER -C_ZERO: - .WORD X_CONSTANT ; Put next word on stack - .WORD $0000 - -W_1: ; Put 1 on stack - .BYTE $81,'1'+$80 - .WORD W_ZERO -C_1: - .WORD X_CONSTANT ; Put next word on stack - .WORD 0001h - -W_2: - .BYTE $81,'2'+$80 - .WORD W_1 -C_2: - .WORD X_CONSTANT ; Put next word on stack - .WORD 0002h - -W_3: - .BYTE $81,'3'+$80 - .WORD W_2 -C_3: - .WORD X_CONSTANT ; Put next word on stack - .WORD 0003h - -W_BL: ; Leaves ASCII for blank on stack - .BYTE $82,"B",'L'+$80 - .WORD W_3 -C_BL: - .WORD X_CONSTANT ; Put next word on stack - .WORD 0020h - -W_CL: - .BYTE $83,"C/",'L'+$80 - .WORD W_BL -C_CL: - .WORD E_COLON ; Interpret following word sequence - .WORD C_UCL - .WORD C_FETCH ; Get word from addr on stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_FIRST: - .BYTE $85,"FIRS",'T'+$80 - .WORD W_CL -C_FIRST: - .WORD E_COLON ; Interpret following word sequence - .WORD C_UFIRST ; Put UFIRST addr on stack - .WORD C_FETCH ; Get word from addr on stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_LIMIT: - .BYTE $85,"LIMI",'T'+$80 - .WORD W_FIRST -C_LIMIT: - .WORD E_COLON ; Interpret following word sequence - .WORD C_ULIMIT ; Put ULIMIT on stack - .WORD C_FETCH ; Get word from addr on stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_BBUF: - .BYTE $85,"B/BU",'F'+$80 - .WORD W_LIMIT -C_BBUF: - .WORD E_COLON ; Interpret following word sequence - .WORD C_UBBUF - .WORD C_FETCH ; Get word from addr on stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_BSCR: - .BYTE $85,"B/SC",'R'+$80 - .WORD W_BBUF -C_BSCR: - .WORD E_COLON ; Interpret following word sequence - .WORD C_UBSCR ; Number of buffers per block - .WORD C_FETCH ; Get word from addr on stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_S0: ; Push S0 (initial data stack pointer) - .BYTE $82,"S",'0'+$80 - .WORD W_BSCR -C_S0: - .WORD X_USER ; Put next word on stack then do next - .WORD S0-SYSTEM - -W_R0: - .BYTE $82,"R",'0'+$80 - .WORD W_S0 -C_R0: - .WORD X_USER ; Put next word on stack then do next - .WORD R0-SYSTEM - -W_TIB: - .BYTE $83,"TI",'B'+$80 - .WORD W_R0 -C_TIB: - .WORD X_USER ; Put next word on stack then do next - .WORD TIB-SYSTEM - -W_WIDTH: - .BYTE $85,"WIDT",'H'+$80 - .WORD W_TIB -C_WIDTH: - .WORD X_USER ; Put next word on stack then do next - .WORD WIDTH-SYSTEM - -W_WARNING: ; Put WARNING addr on stack - .BYTE $87,"WARNIN",'G'+$80 - .WORD W_WIDTH -C_WARNING: - .WORD X_USER ; Put next word on stack then do next - .WORD WARNING-SYSTEM - -W_FENCE: - .BYTE $85,"FENC",'E'+$80 - .WORD W_WARNING -C_FENCE: - .WORD X_USER ; Put next word on stack then do next - .WORD FENCE-SYSTEM - -W_DP: ; Dictionary pointer addr on stack - .BYTE $82,"D",'P'+$80 - .WORD W_FENCE -C_DP: - .WORD X_USER ; Put next word on stack then do next - .WORD DP-SYSTEM - -W_VOC_LINK: - .BYTE $88,"VOC-LIN",'K'+$80 - .WORD W_DP -C_VOC_LINK: - .WORD X_USER ; Put next word on stack then do next - .WORD VOC_LINK-SYSTEM - -W_BLK: - .BYTE $83,"BL",'K'+$80 - .WORD W_VOC_LINK -C_BLK: - .WORD X_USER ; Put next word on stack then do next - .WORD BLK-SYSTEM - -W_TOIN: - .BYTE $83,">I",'N'+$80 - .WORD W_BLK -C_TOIN: - .WORD X_USER ; Put next word on stack then do next - .WORD TOIN-SYSTEM - -W_OUT: ; Put OUT buffer count addr on stack - .BYTE $83,"OU",'T'+$80 - .WORD W_TOIN -C_OUT: - .WORD X_USER ; Put next word on stack then do next - .WORD OUT-SYSTEM - -W_SCR: - .BYTE $83,"SC",'R'+$80 - .WORD W_OUT -C_SCR: - .WORD X_USER ; Put next word on stack then do next - .WORD SCR-SYSTEM - -W_OFFSET: ; Put disk block offset on stack - .BYTE $86,"OFFSE",'T'+$80 - .WORD W_SCR -C_OFFSET: - .WORD X_USER ; Put next word on stack then do next - .WORD OFFSET-SYSTEM - -W_CONTEXT: - .BYTE $87,"CONTEX",'T'+$80 - .WORD W_OFFSET -C_CONTEXT: - .WORD X_USER ; Put next word on stack then do next - .WORD CONTEXT-SYSTEM - -W_CURRENT: - .BYTE $87,"CURREN",'T'+$80 - .WORD W_CONTEXT -C_CURRENT: - .WORD X_USER ; Put next word on stack then do next - .WORD CURRENT-SYSTEM - -W_STATE: ; Push STATE addr - .BYTE $85,"STAT",'E'+$80 - .WORD W_CURRENT -C_STATE: - .WORD X_USER ; Put next word on stack then do next - .WORD STATE-SYSTEM - -W_BASE: ; Put BASE addr on stack - .BYTE $84,"BAS",'E'+$80 - .WORD W_STATE -C_BASE: - .WORD X_USER ; Put next word on stack then do next - .WORD BASE-SYSTEM - -W_DPL: - .BYTE $83,"DP",'L'+$80 - .WORD W_BASE -C_DPL: - .WORD X_USER ; Put next word on stack then do next - .WORD DPL-SYSTEM - -W_FLD: - .BYTE $83,"FL",'D'+$80 - .WORD W_DPL -C_FLD: - .WORD X_USER ; Put next word on stack then do next - .WORD FLD-SYSTEM - -W_CSP: ; Push check stack pointer addr - .BYTE $83,"CS",'P'+$80 - .WORD W_FLD -C_CSP: - .WORD X_USER ; Put next word on stack then do next - .WORD CSP-SYSTEM - -W_RHASH: - .BYTE $82,"R",'#'+$80 - .WORD W_CSP -C_RHASH: - .WORD X_USER ; Put next word on stack then do next - .WORD RHASH-SYSTEM - -W_HLD: - .BYTE $83,"HL",'D'+$80 - .WORD W_RHASH -C_HLD: - .WORD X_USER ; Put next word on stack then do next - .WORD HLD-SYSTEM - -W_UCL: - .BYTE $84,"UC/",'L'+$80 - .WORD W_HLD -C_UCL: - .WORD X_USER ; Put next word on stack then do next - .WORD UCL-SYSTEM - -W_UFIRST: - .BYTE $86,"UFIRS",'T'+$80 - .WORD W_UCL -C_UFIRST: - .WORD X_USER ; Put next word on stack then do next - .WORD UFIRST-SYSTEM - -W_ULIMIT: - .BYTE $86,"ULIMI",'T'+$80 - .WORD W_UFIRST -C_ULIMIT: - .WORD X_USER ; Put next word on stack then do next - .WORD ULIMIT-SYSTEM - -W_UBBUF: - .BYTE $86,"UB/BU",'F'+$80 - .WORD W_ULIMIT -C_UBBUF: - .WORD X_USER ; Put next word on stack then do next - .WORD UBBUF-SYSTEM - -W_UBSCR: - .BYTE $86,"UB/SC",'R'+$80 - .WORD W_UBBUF -C_UBSCR: - .WORD X_USER ; Put next word on stack then do next - .WORD UBSCR-SYSTEM - -W_UTERMINAL: - .BYTE 8Ah,"U?TERMINA",'L'+$80 - .WORD W_UBSCR -C_UTERMINAL: - .WORD X_USER ; Put next word on stack then do next - .WORD UTERMNL-SYSTEM - -W_UKEY: ; Put UKEY addr on stack - .BYTE $84,"UKE",'Y'+$80 - .WORD W_UTERMINAL -C_UKEY: - .WORD X_USER ; Put next word on stack then do next - .WORD UKEY-SYSTEM - -W_UEMIT: ; Put UEMIT addr on stack - .BYTE $85,"UEMI",'T'+$80 - .WORD W_UKEY -C_UEMIT: - .WORD X_USER ; Put next word on stack then do next - .WORD UEMIT-SYSTEM - -W_UCR: ; Push UCR addr - .BYTE $83,"UC",'R'+$80 - .WORD W_UEMIT -C_UCR: - .WORD X_USER ; Put next word on stack then do next - .WORD UCR-SYSTEM - -W_URW: - .BYTE $84,"UR/",'W'+$80 - .WORD W_UCR -C_URW: - .WORD X_USER ; Put next word on stack then do next - .WORD URW-SYSTEM - -W_UABORT: ; Put UABORT on stack - .BYTE $86,"UABOR",'T'+$80 - .WORD W_URW -C_UABORT: - .WORD X_USER ; Put next word on stack then do next - .WORD UABORT-SYSTEM - -W_RAF: - .BYTE $83,"RA",'F'+$80 - .WORD W_UABORT -C_RAF: - .WORD X_USER ; Put next word on stack then do next - .WORD RAF-SYSTEM - -W_RBC: - .BYTE $83,"RB",'C'+$80 - .WORD W_RAF -C_RBC: - .WORD X_USER ; Put next word on stack then do next - .WORD RBC-SYSTEM - -W_RDE: - .BYTE $83,"RD",'E'+$80 - .WORD W_RBC -C_RDE - .WORD X_USER ; Put next word on stack then do next - .WORD RDE-SYSTEM - -W_RHL: - .BYTE $83,"RH",'L'+$80 - .WORD W_RDE -C_RHL: - .WORD X_USER ; Put next word on stack then do next - .WORD RHL-SYSTEM - -W_RIX: - .BYTE $83,"RI",'X'+$80 - .WORD W_RHL -C_RIX: - .WORD X_USER ; Put next word on stack then do next - .WORD RIX-SYSTEM - -W_RIY: - .BYTE $83,"RI",'Y'+$80 - .WORD W_RIX -C_RIY: - .WORD X_USER ; Put next word on stack then do next - .WORD RIY-SYSTEM - -W_RAF2: - .BYTE $84,"RAF",2Ch+$80 - .WORD W_RIY -C_RAF2: - .WORD X_USER ; Put next word on stack then do next - .WORD RAF2-SYSTEM - -W_RBC2: - .BYTE $84,"RBC",2Ch+$80 - .WORD W_RAF2 -C_RBC2: - .WORD X_USER ; Put next word on stack then do next - .WORD RBC2-SYSTEM - -W_RDE2: - .BYTE $84,"RDE",2Ch+$80 - .WORD W_RBC2 -C_RDE2: - .WORD X_USER ; Put next word on stack then do next - .WORD RDE2-SYSTEM - -W_RHL2: - .BYTE $84,"RHL",2Ch+$80 - .WORD W_RDE2 -C_RHL2: - .WORD X_USER ; Put next word on stack then do next - .WORD RHL2-SYSTEM - -W_RA: - .BYTE $82,"R",'A'+$80 - .WORD W_RHL2 -C_RA: - .WORD X_USER ; Put next word on stack then do next - .WORD RAF+1-SYSTEM - -W_RF: - .BYTE $82,"R",'F'+$80 - .WORD W_RA -C_RF: - .WORD X_USER ; Put next word on stack then do next - .WORD RAF-SYSTEM - -W_RB: - .BYTE $82,"R",'B'+$80 - .WORD W_RF -C_RB: - .WORD X_USER ; Put next word on stack then do next - .WORD RBC+1-SYSTEM - -W_RC: - .BYTE $82,"R",'C'+$80 - .WORD W_RB -C_RC: - .WORD X_USER ; Put next word on stack then do next - .WORD RBC-SYSTEM - -W_RD: - .BYTE $82,"R",'D'+$80 - .WORD W_RC -C_RD: - .WORD X_USER ; Put next word on stack then do next - .WORD RDE+1-SYSTEM - -W_RE: - .BYTE $82,"R",'E'+$80 - .WORD W_RD -C_RE: - .WORD X_USER ; Put next word on stack then do next - .WORD RDE-SYSTEM - -W_RH: - .BYTE $82,"R",'H'+$80 - .WORD W_RE -C_RH: - .WORD X_USER ; Put next word on stack then do next - .WORD RHL+1-SYSTEM - -W_RL: - .BYTE $82,"R",'L'+$80 - .WORD W_RH -C_RL: - .WORD X_USER ; Put next word on stack then do next - .WORD RHL-SYSTEM - -W_CALL: - .BYTE $84,"CAL",'L'+$80 - .WORD W_RL -C_CALL: - .WORD 2+$ ; Vector to code - POP HL ; Address of routine CALLed - PUSH DE ; Save register - PUSH BC ; Save register - LD A,$C3 ; Hex code for JMP - LD (JPCODE),A ; Save it - LD (JPVECT),HL ; Save jump vector - LD HL,(RAF) ; Get register AF - PUSH HL ; Onto stack - POP AF ; POP into AF - LD BC,(RBC) ; Get register BC - LD DE,(RDE) ; Get register DE - LD HL,(RHL) ; Get register HL - LD IX,(RIX) ; Get register IX - LD IY,(RIY) ; Get register IY - CALL JPCODE ; Call jump to code - LD (RIY),IY ; Save register IY - LD (RIX),IX ; Save register IX - LD (RBC),BC ; Save register BC - LD (RDE),DE ; Save register DE - LD (RHL),HL ; Save register HL - PUSH AF ; Save register AF - POP HL ; Into HL - LD (RAF),HL ; Into memory - POP BC ; Restore BC - POP DE ; Restore DE - JP NEXT ; - -W_1PLUS: ; 1 plus - .BYTE $82,"1",'+'+$80 - .WORD W_CALL -C_1PLUS: - .WORD 2+$ ; Vector to code - POP HL ; get n - INC HL ; add 1 - JP NEXTS1 ; save result & NEXT - -W_2PLUS: ; 2 plus - .BYTE $82,"2",'+'+$80 - .WORD W_1PLUS -C_2PLUS: - .WORD 2+$ ; Vector to code - POP HL ; get n - INC HL ; add 1 - INC HL ; add 2 - JP NEXTS1 ; save result & NEXT - -W_1MINUS: ; 1 minus - .BYTE $82,"1",'-'+$80 - .WORD W_2PLUS -C_1MINUS: - .WORD 2+$ ; Vector to code - POP HL ; get n - DEC HL ; add 1 - JP NEXTS1 ; save result & NEXT - -W_2MINUS: ; 2 minus - .BYTE $82,"2",'-'+$80 - .WORD W_1MINUS -C_2MINUS: - .WORD 2+$ ; Vector to code - POP HL ; get n - DEC HL ; subtract 1 - DEC HL ; subtract 2 - JP NEXTS1 ; save result & NEXT - -W_HERE: ; Dictionary pointer onto stack - .BYTE $84,"HER",'E'+$80 - .WORD W_2MINUS -C_HERE: - .WORD E_COLON ; Interpret following word sequence - .WORD C_DP ; Dictionary pointer addr on stack - .WORD C_FETCH ; Get word from addr on stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_ALLOT: - .BYTE $85,"ALLO",'T'+$80 - .WORD W_HERE -C_ALLOT: - .WORD E_COLON ; Interpret following word sequence - .WORD C_DP ; Dictionary pointer addr on stack - .WORD C_PLUSSTORE ; Add n1 to addr - .WORD C_STOP ; Pop BC from return stack (=next) - -W_COMMA: ; Reserve 2 bytes and save n - .BYTE $81,','+$80 - .WORD W_ALLOT -C_COMMA: - .WORD E_COLON ; Interpret following word sequence - .WORD C_HERE ; Next free dictionary pointer onto stack - .WORD C_STORE ; Store word at addr - .WORD C_2 ; - .WORD C_ALLOT ; Move pointer - .WORD C_STOP ; Pop BC from return stack (=next) - -W_CCOMMA: - .BYTE $82,"C",','+$80 - .WORD W_COMMA -C_CCOMMA: - .WORD E_COLON ; Interpret following word sequence - .WORD C_HERE ; Dictionary pointer onto stack - .WORD C_CSTORE ; Store byte at addr - .WORD C_1 ; Put 1 on stack - .WORD C_ALLOT - .WORD C_STOP ; Pop BC from return stack (=next) - -W_MINUS: - .BYTE $81,'-'+$80 - .WORD W_CCOMMA -C_MINUS: - .WORD 2+$ ; Vector to code - POP DE ; get n1 - POP HL ; get n2 - CALL MINUS16 ; call subtract routine - JP NEXTS1 ; save & NEXT - -MINUS16: - LD A,L ; gel low byte - SUB E ; subtract low bytes - LD L,A ; save low byte result - LD A,H ; get high byte - SBC A,D ; subtract high bytes - LD H,A ; save high byte result - RET ; - -W_EQUALS: - .BYTE $81,'='+$80 - .WORD W_MINUS -C_EQUALS: - .WORD E_COLON ; Interpret following word sequence - .WORD C_MINUS - .WORD C_0EQUALS ; =0 - .WORD C_STOP ; Pop BC from return stack (=next) - -W_LESSTHAN: - .BYTE $81,'<'+$80 - .WORD W_EQUALS -C_LESSTHAN: - .WORD 2+$ ; Vector to code - POP DE - POP HL - LD A,D - XOR H - JP M,J298C - CALL MINUS16 -J298C: - INC H - DEC H - JP M,J2997 - LD HL,0000 - JP NEXTS1 ; Save & NEXT -J2997: - LD HL,0001 - JP NEXTS1 ; Save & NEXT - -W_ULESS: ; IF stack-1 < stack_top leave true flag - .BYTE $82,"U",'<'+$80 - .WORD W_LESSTHAN -C_ULESS: - .WORD E_COLON ; Interpret following word sequence - .WORD C_2DUP ; Dup top 2 values on stack - .WORD C_XOR ; Exclusive OR them - .WORD C_0LESS ; Less than 0 - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B0000-$ ; 000Ch - .WORD C_DROP ; Drop top value from stack - .WORD C_0LESS ; Less than 0 - .WORD C_0EQUALS ; =0 - .WORD C_BRANCH ; Add following offset to BC - .WORD B0001-$ ; 0006h -B0000: - .WORD C_MINUS - .WORD C_0LESS ; Less than 0 -B0001: - .WORD C_STOP ; Pop BC from return stack (=next) - -W_GREATER: - .BYTE $81,'>'+$80 - .WORD W_ULESS -C_GREATER: - .WORD E_COLON ; Interpret following word sequence - .WORD C_SWAP ; Swap top 2 values on stack - .WORD C_LESSTHAN - .WORD C_STOP ; Pop BC from return stack (=next) - -W_ROT: ; 3rd valu down to top of stack - .BYTE $83,"RO",'T'+$80 - .WORD W_GREATER -C_ROT: - .WORD 2+$ ; Vector to code - POP DE ; Top value - POP HL ; Next one down - EX (SP),HL ; Exchange with third - JP NEXTS2 ; Save both & NEXT - -W_PICK: - .BYTE $84,"PIC",'K'+$80 - .WORD W_ROT -C_PICK: - .WORD E_COLON ; Interpret following word sequence - .WORD C_DUP ; Duplicate top value on stack - .WORD C_PLUS ; n1 + n2 - .WORD C_SPFETCH ; Stack pointer onto stack - .WORD C_PLUS ; n1 + n2 - .WORD C_FETCH ; Get word from addr on stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_SPACE: - .BYTE $85,"SPAC",'E'+$80 - .WORD W_PICK -C_SPACE: - .WORD E_COLON ; Interpret following word sequence - .WORD C_BL ; Leaves ASCII for space on stack - .WORD C_EMIT ; Output CHR from stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_QUERYDUP: - .BYTE $84,"?DU",'P'+$80 - .WORD W_SPACE -C_QUERYDUP: - .WORD E_COLON ; Interpret following word sequence - .WORD C_DUP ; Duplicate top value on stack - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B0002-$ ; 0004h - .WORD C_DUP ; Duplicate top value on stack -B0002: - .WORD C_STOP ; Pop BC from return stack (=next) - -W_TRAVERSE: - .BYTE $88,"TRAVERS",'E'+$80 - .WORD W_QUERYDUP -C_TRAVERSE: - .WORD E_COLON ; Interpret following word sequence - .WORD C_SWAP ; Swap top 2 values on stack -B0054: - .WORD C_OVER ; Copy 2nd down to top of stack - .WORD C_PLUS ; n1 + n2 - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 007Fh - .WORD C_OVER ; Copy 2nd down to top of stack - .WORD C_CFETCH ; Get byte from addr on stack - .WORD C_LESSTHAN - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B0054-$ ; FFF0h - .WORD C_SWAP ; Swap top 2 values on stack - .WORD C_DROP ; Drop top value from stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_LATEST: - .BYTE $86,"LATES",'T'+$80 - .WORD W_TRAVERSE -C_LATEST: - .WORD E_COLON ; Interpret following word sequence - .WORD C_CURRENT - .WORD C_FETCH ; Get word from addr on stack - .WORD C_FETCH ; Get word from addr on stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_LFA: - .BYTE $83,"LF",'A'+$80 - .WORD W_LATEST -C_LFA: - .WORD E_COLON ; Interpret following word sequence - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 0004h - .WORD C_MINUS - .WORD C_STOP ; Pop BC from return stack (=next) - -W_CFA: - .BYTE $83,"CF",'A'+$80 - .WORD W_LFA -C_CFA: - .WORD 2+$ ; Vector to code - POP HL ; get n - DEC HL ; subtract 1 - DEC HL ; subtract 2 - JP NEXTS1 ; save result & NEXT -W_NFA: - .BYTE $83,"NF",'A'+$80 - .WORD W_CFA -C_NFA: - .WORD E_COLON ; Interpret following word sequence - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 0005h - .WORD C_MINUS - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD $FFFF - .WORD C_TRAVERSE - .WORD C_STOP ; Pop BC from return stack (=next) - -W_PFA: ; Convert NFA to PFA - .BYTE $83,"PF",'A'+$80 - .WORD W_NFA -C_PFA: - .WORD E_COLON ; Interpret following word sequence - .WORD C_1 ; Traverse up memory - .WORD C_TRAVERSE ; End of name on stack - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 0005h ; Offset to start of word code - .WORD C_PLUS ; n1 + n2 - .WORD C_STOP ; Pop BC from return stack (=next) - -W_CSPSTORE: - .BYTE $84,"!CS",'P'+$80 - .WORD W_PFA -C_CSPSTORE: - .WORD E_COLON ; Interpret following word sequence - .WORD C_SPFETCH ; Stack pointer onto stack - .WORD C_CSP ; Push check stack pointer addr - .WORD C_STORE ; Store word at addr - .WORD C_STOP ; Pop BC from return stack (=next) - -W_QERROR: - .BYTE $86,"?ERRO",'R'+$80 - .WORD W_CSPSTORE -C_QERROR: - .WORD E_COLON ; Interpret following word sequence - .WORD C_SWAP ; Swap top 2 values on stack - .WORD C_0BRANCH ; Branch if no error - .WORD B0003-$ ; 0008h - .WORD C_ERROR - .WORD C_BRANCH ; Add following offset to BC - .WORD B0004-$ ; 0004h -B0003: - .WORD C_DROP ; Drop error no. -B0004: - .WORD C_STOP ; Pop BC from return stack (=next) - -W_QCOMP: ; Error if not in compile mode - .BYTE $85,"?COM",'P'+$80 - .WORD W_QERROR -C_QCOMP: - .WORD E_COLON ; Interpret following word sequence - .WORD C_STATE ; Push STATE addr - .WORD C_FETCH ; Get word from addr on stack - .WORD C_0EQUALS ; =0 - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 0011h ; Error message number - .WORD C_QERROR ; Error if state <> 0 - .WORD C_STOP ; Pop BC from return stack (=next) - -W_QEXEC: ; Error not if not in execute mode - .BYTE $85,"?EXE",'C'+$80 - .WORD W_QCOMP -C_QEXEC: - .WORD E_COLON ; Interpret following word sequence - .WORD C_STATE ; Push STATE addr - .WORD C_FETCH ; Get word from addr on stack - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 0012h ; Error not if not in execute mode - .WORD C_QERROR - .WORD C_STOP ; Pop BC from return stack (=next) - -W_QPAIRS: - .BYTE $86,"?PAIR",'S'+$80 - .WORD W_QEXEC -C_QPAIRS: - .WORD E_COLON ; Interpret following word sequence - .WORD C_MINUS - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 0013h - .WORD C_QERROR - .WORD C_STOP ; Pop BC from return stack (=next) - -W_WHATSTACK: ; Check stack pointer, error if not ok - .BYTE $84,"?CS",'P'+$80 - .WORD W_QPAIRS -C_WHATSTACK: - .WORD E_COLON ; Interpret following word sequence - .WORD C_SPFETCH ; Stack pointer onto stack - .WORD C_CSP ; Push check stack pointer addr - .WORD C_FETCH ; Get check stack pointer - .WORD C_MINUS ; If ok then result is 0 - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 0014h ; Error no if not ok - .WORD C_QERROR ; Error if stack top -1 <> 0 - .WORD C_STOP ; Pop BC from return stack (=next) - -W_QLOADING: - .BYTE $88,"?LOADIN",'G'+$80 - .WORD W_WHATSTACK -C_QLOADING: - .WORD E_COLON ; Interpret following word sequence - .WORD C_BLK - .WORD C_FETCH ; Get word from addr on stack - .WORD C_0EQUALS ; =0 - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 0016h - .WORD C_QERROR - .WORD C_STOP ; Pop BC from return stack (=next) - -W_COMPILE: - .BYTE $87,"COMPIL",'E'+$80 - .WORD W_QLOADING -C_COMPILE: - .WORD E_COLON ; Interpret following word sequence - .WORD C_QCOMP ; Error if not in compile mode - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_DUP ; Bump return address and put back - .WORD C_2PLUS ; - .WORD C_MOVER ; - .WORD C_FETCH ; Get word from addr on stack - .WORD C_COMMA ; Reserve 2 bytes and save n - .WORD C_STOP ; Pop BC from return stack (=next) - -W_LEFTBRKT: ; Set STATE to execute - .BYTE $81,'['+$80 - .WORD W_COMPILE -C_LEFTBRKT: - .WORD E_COLON ; Interpret following word sequence - .WORD C_ZERO ; Put zero on stack - .WORD C_STATE ; Push STATE addr - .WORD C_STORE ; Store word at addr - .WORD C_STOP ; Pop BC from return stack (=next) - -W_RIGHTBRKT: ; Set STATE to compile - .BYTE $81,']'+$80 - .WORD W_LEFTBRKT -C_RIGHTBRKT: - .WORD E_COLON ; Interpret following word sequence - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 00$C0 - .WORD C_STATE ; Push STATE addr - .WORD C_STORE ; Set STATE to execute - .WORD C_STOP ; Pop BC from return stack (=next) - -W_SMUDGE: - .BYTE $86,"SMUDG",'E'+$80 - .WORD W_RIGHTBRKT -C_SMUDGE: - .WORD E_COLON ; Interpret following word sequence - .WORD C_LATEST ; Push top words NFA - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 0020h - .WORD C_TOGGLE ; XOR (addr) with byte - .WORD C_STOP ; Pop BC from return stack (=next) - -W_HEX: - .BYTE $83,"HE",'X'+$80 - .WORD W_SMUDGE -C_HEX: - .WORD E_COLON ; Interpret following word sequence - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 0010h - .WORD C_BASE ; Put BASE addr on stack - .WORD C_STORE ; Store word at addr - .WORD C_STOP ; Pop BC from return stack (=next) - -W_DECIMAL: ; Sets decimal mode - .BYTE $87,"DECIMA",'L'+$80 - .WORD W_HEX -C_DECIMAL: - .WORD E_COLON ; Interpret following word sequence - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 00$0A ; Sets decimal value - .WORD C_BASE ; Put BASE addr on stack - .WORD C_STORE ; Store word at addr - .WORD C_STOP ; Pop BC from return stack (=next) - -W_CCODE: ; Stop compillation & terminate word - .BYTE $87,"<; CODE",'>'+$80 - .WORD W_DECIMAL -C_CCODE: - .WORD E_COLON ; Interpret following word sequence - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_LATEST ; Push top words NFA - .WORD C_PFA ; Convert NFA to PFA - .WORD C_CFA ; Convert PFA to CFA - .WORD C_STORE ; Store word at addr - .WORD C_STOP ; Pop BC from return stack (=next) - -W_SCCODE: - .BYTE $C5,"; COD",'E'+$80 - .WORD W_CCODE -C_SCCODE: - .WORD E_COLON ; Interpret following word sequence - .WORD C_WHATSTACK ; Check stack pointer, error if not ok - .WORD C_COMPILE ; Compile next word into dictionary - .WORD C_CCODE - .WORD C_LEFTBRKT ; Set STATE to execute - .WORD C_TASK - .WORD C_STOP ; Pop BC from return stack (=next) - -W_CREATE: - .BYTE $86,"CREAT",'E'+$80 - .WORD W_SCCODE -C_CREATE: - .WORD E_COLON ; Interpret following word sequence - .WORD C_ZERO ; Put zero on stack - .WORD C_CONSTANT - .WORD C_STOP ; Pop BC from return stack (=next) - -W_DOES: - .BYTE $85,"DOES",'>'+$80 - .WORD W_CREATE -C_DOES: - .WORD E_COLON ; Interpret following word sequence - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_LATEST ; Push top words NFA - .WORD C_PFA ; Convert NFA to PFA - .WORD C_STORE ; Store word at addr - .WORD C_CCODE ; Execute following machine code - -X_DOES: - LD HL,(RPP) ; Get return stack pointer - DEC HL ; Push next pointer - LD (HL),B ; - DEC HL ; - LD (HL),C ; - LD (RPP),HL - INC DE - EX DE,HL - LD C,(HL) - INC HL - LD B,(HL) - INC HL - JP NEXTS1 ; Save & NEXT - -W_COUNT: ; Convert string at addr to addr + length - .BYTE $85,"COUN",'T'+$80 - .WORD W_DOES -C_COUNT: - .WORD E_COLON ; Interpret following word sequence - .WORD C_DUP ; Duplicate address - .WORD C_1PLUS ; Add 1 (points to string start) - .WORD C_SWAP ; Get address back - .WORD C_CFETCH ; Get byte from addr on stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_TYPE: ; Output n bytes from addr - .BYTE $84,"TYP",'E'+$80 - .WORD W_COUNT -C_TYPE: - .WORD E_COLON ; Interpret following word sequence - .WORD C_QUERYDUP ; Copy length if length <> 0 - .WORD C_0BRANCH ; Branch if length = 0 - .WORD B0005-$ ; 0018h - .WORD C_OVER ; Copy address to stack top - .WORD C_PLUS ; Add to length - .WORD C_SWAP ; Swap top 2 values on stack - .WORD C_LDO ; Put start & end loop values on RPP -B004F: - .WORD C_I ; Copy LOOP index to data stack - .WORD C_CFETCH ; Get byte from string - .WORD C_EMIT ; Output CHR from stack - .WORD C_LLOOP ; Increment loop & branch if not done - .WORD B004F-$ ; FFF8h - .WORD C_BRANCH ; Done so branch to next - .WORD B0006-$ ; 0004h -B0005: - .WORD C_DROP ; Drop string address -B0006: - .WORD C_STOP ; Pop BC from return stack (=next) - -W_TRAILING: - .BYTE $89,"-TRAILIN",'G'+$80 - .WORD W_TYPE -C_TRAILING: - .WORD E_COLON ; Interpret following word sequence - .WORD C_DUP ; Duplicate top value on stack - .WORD C_ZERO ; Put zero on stack - .WORD C_LDO ; Put start & end loop values on RPP -B0009: - .WORD C_OVER ; Copy 2nd down to top of stack - .WORD C_OVER ; Copy 2nd down to top of stack - .WORD C_PLUS ; n1 + n2 - .WORD C_1 ; Put 1 on stack - .WORD C_MINUS - .WORD C_CFETCH ; Get byte from addr on stack - .WORD C_BL ; Leaves ASCII for space on stack - .WORD C_MINUS - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B0007-$ ; 0008h - .WORD C_LEAVE ; Quit loop by making index = limit - .WORD C_BRANCH ; Add following offset to BC - .WORD B0008-$ ; 0006h -B0007: - .WORD C_1 ; Put 1 on stack - .WORD C_MINUS -B0008: - .WORD C_LLOOP ; Increment loop & branch if not done - .WORD B0009-$ ; FFE0h - .WORD C_STOP ; Pop BC from return stack (=next) - -W_CQUOTE: ; Output following string - .BYTE $84,"<.",22h,'>'+$80 - .WORD W_TRAILING -C_CQUOTE: - .WORD E_COLON ; Interpret following word sequence - .WORD C_RFETCH ; Copy return stack top to data stack - .WORD C_COUNT ; Convert string at addr to addr + length - .WORD C_DUP ; Duplicate top value on stack - .WORD C_1PLUS ; 1 plus - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_PLUS ; Add length of string +1 - .WORD C_MOVER ; Move value from data to return stack - .WORD C_TYPE ; Output n bytes from addr - .WORD C_STOP ; Pop BC from return stack (=next) - -W_QUOTE: ; Accept following text - .BYTE $C2,".",$22+$80 - .WORD W_CQUOTE -C_QUOTE: - .WORD E_COLON ; Interpret following word sequence - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD $0022 - .WORD C_STATE ; Push STATE addr - .WORD C_FETCH ; Get word from addr on stack - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B000A-$ ; 0012h - .WORD C_COMPILE ; Compile next word into dictionary - .WORD C_CQUOTE - .WORD C_WORD - .WORD C_CFETCH ; Get byte from addr on stack - .WORD C_1PLUS ; 1 plus - .WORD C_ALLOT - .WORD C_BRANCH ; Add following offset to BC - .WORD B000B-$ ; 0008h -B000A: - .WORD C_WORD - .WORD C_COUNT ; Convert string at addr to addr + length - .WORD C_TYPE ; Output n bytes from addr -B000B: - .WORD C_STOP ; Pop BC from return stack (=next) - -W_EXPECT: - .BYTE $86,"EXPEC",'T'+$80 - .WORD W_QUOTE -C_EXPECT: - .WORD E_COLON ; Interpret following word sequence - .WORD C_OVER ; Copy buffer start addr - .WORD C_PLUS ; Add to length to give start,end - .WORD C_OVER ; Copy start - .WORD C_LDO ; Put start & end loop values on RPP -B0012: - .WORD C_KEY ; Wait for key, value on stack - .WORD C_DUP ; Duplicate key value - .WORD C_LIT ; Push backspace addr - .WORD BACKSPACE - .WORD C_FETCH ; Get backspace value - .WORD C_EQUALS ; Was it backspace ? - .WORD C_0BRANCH ; If not then jump - .WORD B000C-$ ; 002Ah - .WORD C_DROP ; Drop top value from stack - .WORD C_DUP ; Duplicate top value on stack - .WORD C_I ; Copy LOOP index to data stack - .WORD C_EQUALS - .WORD C_DUP ; Duplicate top value on stack - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_2 - .WORD C_MINUS - .WORD C_PLUS ; n1 + n2 - .WORD C_MOVER ; Move value from data to return stack - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B000D-$ ; 00$0A - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 0007h - .WORD C_BRANCH ; Add following offset to BC - .WORD B000E-$ ; 0006h -B000D: - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 0008h -B000E: - .WORD C_BRANCH ; Add following offset to BC - .WORD B000F-$ ; 0028h -B000C: - .WORD C_DUP ; Duplicate key value - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 00$0D ; CR - .WORD C_EQUALS ; Was it cariage return - .WORD C_0BRANCH ; If not then jump - .WORD B0010-$ ; 000Eh - .WORD C_LEAVE ; Quit loop by making index = limit - .WORD C_DROP ; Drop top value from stack - .WORD C_BL ; Leaves ASCII for space on stack - .WORD C_ZERO ; Put zero on stack - .WORD C_BRANCH ; Add following offset to BC - .WORD B0011-$ ; 0004h -B0010: - .WORD C_DUP ; Duplicate key value -B0011: - .WORD C_I ; Copy LOOP index to data stack - .WORD C_CSTORE ; Store byte at addr - .WORD C_ZERO ; Put zero on stack - .WORD C_I ; Copy LOOP index to data stack - .WORD C_1PLUS ; 1 plus - .WORD C_STORE ; Store word at addr -B000F: - .WORD C_EMIT ; Output CHR from stack - .WORD C_LLOOP ; Increment loop & branch if not done - .WORD B0012-$ ; FF9Eh - .WORD C_DROP ; Drop top value from stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_QUERY: - .BYTE $85,"QUER",'Y'+$80 - .WORD W_EXPECT -C_QUERY: - .WORD E_COLON ; Interpret following word sequence - .WORD C_TIB ; Put TIB addr on stack - .WORD C_FETCH ; Get word from addr on stack - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD $0050 ; Max line length 50h - .WORD C_EXPECT ; Get line - .WORD C_ZERO ; Put zero on stack - .WORD C_TOIN ; Current input buffer offset - .WORD C_STORE ; Store word at addr - .WORD C_STOP ; Pop BC from return stack (=next) - -W_NULL: - .BYTE $C1,$80 - .WORD W_QUERY -C_NULL: - .WORD E_COLON ; Interpret following word sequence - .WORD C_BLK - .WORD C_FETCH ; Get word from addr on stack - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B0013-$ ; 002Ah - .WORD C_1 ; Put 1 on stack - .WORD C_BLK - .WORD C_PLUSSTORE ; Add n1 to addr - .WORD C_ZERO ; Put zero on stack - .WORD C_TOIN ; Current input buffer offset - .WORD C_STORE ; Store word at addr - .WORD C_BLK - .WORD C_FETCH ; Get word from addr on stack - .WORD C_BSCR ; Number of buffers per block on stack - .WORD C_1 ; Put 1 on stack - .WORD C_MINUS - .WORD C_AND ; AND - .WORD C_0EQUALS ; =0 - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B0014-$ ; 0008h - .WORD C_QEXEC ; Error not if not in execute mode - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_DROP ; Drop top value from stack -B0014: - .WORD C_BRANCH ; Add following offset to BC - .WORD B0015-$ ; 0006h -B0013: - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_DROP ; Drop top value from stack -B0015: - .WORD C_STOP ; Pop BC from return stack (=next) - -W_FILL: ; Fill with byte n bytes from addr - .BYTE $84,"FIL",'L'+$80 - .WORD W_NULL -C_FILL: - .WORD 2+$ ; Vector to code - LD L,C ; Save BC for now - LD H,B ; - POP DE ; get byte - POP BC ; get n - EX (SP),HL ; get addr and save BC - EX DE,HL ; -NEXT_BYTE: - LD A,B ; Test count - OR C ; - JR Z,NO_COUNT ; If 0 we're done - LD A,L ; Byte into A - LD (DE),A ; Save byte - INC DE ; Next addr - DEC BC ; Decr count - JR NEXT_BYTE ; Loop -NO_COUNT: - POP BC ; Get BC back - JP NEXT - -W_ERASE: ; Fill addr & length from stack with 0 - .BYTE $85,"ERAS",'E'+$80 - .WORD W_FILL -C_ERASE: - .WORD E_COLON ; Interpret following word sequence - .WORD C_ZERO ; Put zero on stack - .WORD C_FILL ; Fill with byte n bytes from addr - .WORD C_STOP ; Pop BC from return stack (=next) - -W_BLANKS: ; Fill addr & length from stack with [SP] - .BYTE $86,"BLANK",'S'+$80 - .WORD W_ERASE -C_BLANKS: - .WORD E_COLON ; Interpret following word sequence - .WORD C_BL ; Leaves ASCII for space on stack - .WORD C_FILL ; Fill with byte n bytes from addr - .WORD C_STOP ; Pop BC from return stack (=next) - -W_HOLD: - .BYTE $84,"HOL",'D'+$80 - .WORD W_BLANKS -C_HOLD: - .WORD E_COLON ; Interpret following word sequence - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD $FFFF - .WORD C_HLD - .WORD C_PLUSSTORE ; Add n1 to addr - .WORD C_HLD - .WORD C_FETCH ; Get word from addr on stack - .WORD C_CSTORE ; Store byte at addr - .WORD C_STOP ; Pop BC from return stack (=next) - -W_PAD: - .BYTE $83,"PA",'D'+$80 - .WORD W_HOLD -C_PAD: - .WORD E_COLON ; Interpret following word sequence - .WORD C_HERE ; Dictionary pointer onto stack - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 0044h - .WORD C_PLUS ; n1 + n2 - .WORD C_STOP ; Pop BC from return stack (=next) - -W_WORD: - .BYTE $84,"WOR",'D'+$80 - .WORD W_PAD -C_WORD: - .WORD E_COLON ; Interpret following word sequence - .WORD C_BLK - .WORD C_FETCH ; Get word from addr on stack - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B0016-$ ; 000Ch - .WORD C_BLK - .WORD C_FETCH ; Get word from addr on stack - .WORD C_BLOCK - .WORD C_BRANCH ; Add following offset to BC - .WORD B0017-$ ; 0006h -B0016: - .WORD C_TIB - .WORD C_FETCH ; Get word from addr on stack -B0017: - .WORD C_TOIN ; Current input buffer offset - .WORD C_FETCH ; Get word from addr on stack - .WORD C_PLUS ; n1 + n2 - .WORD C_SWAP ; Swap top 2 values on stack - .WORD C_ENCLOSE - .WORD C_HERE ; Dictionary pointer onto stack - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 0022h - .WORD C_BLANKS - .WORD C_TOIN ; Current input buffer offset - .WORD C_PLUSSTORE ; Add n1 to addr - .WORD C_OVER ; Copy 2nd down to top of stack - .WORD C_MINUS - .WORD C_MOVER ; Move value from data to return stack - .WORD C_RFETCH ; Return stack top to data stack - .WORD C_HERE ; Dictionary pointer onto stack - .WORD C_CSTORE ; Store byte at addr - .WORD C_PLUS ; n1 + n2 - .WORD C_HERE ; Dictionary pointer onto stack - .WORD C_1PLUS ; 1 plus - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_CMOVE ; Move block - .WORD C_HERE ; Dictionary pointer onto stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_CONVERT: - .BYTE $87,"CONVER",'T'+$80 - .WORD W_WORD -C_CONVERT: - .WORD E_COLON ; Interpret following word sequence -B001A: - .WORD C_1PLUS ; 1 plus - .WORD C_DUP ; Duplicate top value on stack - .WORD C_MOVER ; Move value from data to return stack - .WORD C_CFETCH ; Get byte from addr on stack - .WORD C_BASE ; Put BASE addr on stack - .WORD C_FETCH ; Get word from addr on stack - .WORD C_DIGIT ; Convert digit n2 using base n1 - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B0018-$ ; 002Ch - .WORD C_SWAP ; Swap top 2 values on stack - .WORD C_BASE ; Put BASE addr on stack - .WORD C_FETCH ; Get word from addr on stack - .WORD C_USTAR - .WORD C_DROP ; Drop top value from stack - .WORD C_ROT ; 3rd value down to top of stack - .WORD C_BASE ; Put BASE addr on stack - .WORD C_FETCH ; Get word from addr on stack - .WORD C_USTAR - .WORD C_DPLUS - .WORD C_DPL - .WORD C_FETCH ; Get word from addr on stack - .WORD C_1PLUS ; 1 plus - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B0019-$ ; 0008h - .WORD C_1 ; Put 1 on stack - .WORD C_DPL - .WORD C_PLUSSTORE ; Add n1 to addr -B0019: - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_BRANCH ; Add following offset to BC - .WORD B001A-$ ; FF$C6 -B0018: - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_NUMBER: - .BYTE $86,"NUMBE",'R'+$80 - .WORD W_CONVERT -C_NUMBER: - .WORD E_COLON ; Interpret following word sequence - .WORD C_ZERO ; Put zero on stack - .WORD C_ZERO ; Put zero on stack - .WORD C_ROT ; 3rd value down to top of stack - .WORD C_DUP ; Duplicate top value on stack - .WORD C_1PLUS ; 1 plus - .WORD C_CFETCH ; Get byte from addr on stack - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 002Dh ; '-' - .WORD C_EQUALS ; Is first chr = '-' - .WORD C_DUP ; Duplicate negative flag - .WORD C_MOVER ; Move value from data to return stack - .WORD C_PLUS ; n1 + n2 - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD $FFFF ;-1 -B001C: - .WORD C_DPL - .WORD C_STORE ; Store word at addr - .WORD C_CONVERT - .WORD C_DUP ; Duplicate top value on stack - .WORD C_CFETCH ; Get byte from addr on stack - .WORD C_BL ; Leaves ASCII for space on stack - .WORD C_MINUS - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B001B-$ ; 0016h - .WORD C_DUP ; Duplicate top value on stack - .WORD C_CFETCH ; Get byte from addr on stack - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 002Eh ; '.' - .WORD C_MINUS - .WORD C_ZERO ; Put zero on stack - .WORD C_QERROR - .WORD C_ZERO ; Put zero on stack - .WORD C_BRANCH ; Add following offset to BC - .WORD B001C-$ ; FFDCh -B001B: - .WORD C_DROP ; Drop top value from stack - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B001D-$ ; 0004h - .WORD C_DNEGATE -B001D: - .WORD C_STOP ; Pop BC from return stack (=next) - -W_MFIND: - .BYTE $85,"-FIN",'D'+$80 - .WORD W_NUMBER -C_MFIND: - .WORD E_COLON ; Interpret following word sequence - .WORD C_BL ; Leaves ASCII for space on stack - .WORD C_WORD - .WORD C_CONTEXT - .WORD C_FETCH ; Get word from addr on stack - .WORD C_FETCH ; Get word from addr on stack - .WORD C_FIND ; Find word & return vector,byte & flag - .WORD C_DUP ; Duplicate top value on stack - .WORD C_0EQUALS ; =0 - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B001E-$ ; 00$0A - .WORD C_DROP ; Drop top value from stack - .WORD C_HERE ; Dictionary pointer onto stack - .WORD C_LATEST ; Push top words NFA - .WORD C_FIND ; Find word & return vector,byte & flag -B001E: - .WORD C_STOP ; Pop BC from return stack (=next) - -W_CABORT: - .BYTE $87,"'+$80 - .WORD W_MFIND -C_CABORT: - .WORD E_COLON ; Interpret following word sequence - .WORD C_ABORT - .WORD C_STOP ; Pop BC from return stack (=next) - -W_ERROR: - .BYTE $85,"ERRO",'R'+$80 - .WORD W_CABORT -C_ERROR: - .WORD E_COLON ; Interpret following word sequence - .WORD C_WARNING ; Put WARNING addr on stack - .WORD C_FETCH ; Get word from addr on stack - .WORD C_0LESS ; Less than 0 leaves true - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B001F-$ ; 0004h - .WORD C_CABORT -B001F: - .WORD C_HERE ; Dictionary pointer onto stack - .WORD C_COUNT ; Convert string at addr to addr + length - .WORD C_TYPE ; Output n bytes from addr - .WORD C_CQUOTE ; Output following string - .BYTE S_END7-S_START7 -S_START7: - .BYTE "? " -S_END7: - .WORD C_MESSAGE ; Output message - .WORD C_SPSTORE ; Set initial stack pointer value - .WORD C_BLK - .WORD C_FETCH ; Get word from addr on stack - .WORD C_QUERYDUP - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B0020-$ ; 0008h - .WORD C_TOIN ; Current input buffer offset - .WORD C_FETCH ; Get word from addr on stack - .WORD C_SWAP ; Swap top 2 values on stack -B0020: - .WORD C_QUIT - -W_ID: ; Print definition name from name field addr - .BYTE $83,"ID",'.'+$80 - .WORD W_ERROR -C_ID: - .WORD E_COLON ; Interpret following word sequence - .WORD C_COUNT ; Convert string at addr to addr + length - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 001Fh ; Max length is 1Fh - .WORD C_AND ; AND lenght with 1Fh - .WORD C_TYPE ; Output n bytes from addr - .WORD C_SPACE ; Output space - .WORD C_STOP ; Pop BC from return stack (=next) - -C_XXX1: - .WORD E_COLON ; Interpret following word sequence - .WORD C_MFIND ; Find name returns PFA,length,true or false - .WORD C_0BRANCH ; Branch if name not found - .WORD B0021-$ ; 0010h - .WORD C_DROP ; Drop length - .WORD C_NFA ; Convert PFA to NFA - .WORD C_ID ; Print definition name from name field addr - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD $0004 ; Message 4, name defined twice - .WORD C_MESSAGE ; Output message - .WORD C_SPACE ; Output space -B0021: - .WORD C_HERE ; Dictionary pointer onto stack - .WORD C_DUP ; Duplicate top value on stack - .WORD C_CFETCH ; Get byte from addr on stack - .WORD C_WIDTH - .WORD C_FETCH ; Get word from addr on stack - .WORD C_MIN - .WORD C_1PLUS ; 1 plus - .WORD C_ALLOT ; Which ever is smallest width or namelength - .WORD C_DUP ; Duplicate top value on stack - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD $00A0 - .WORD C_TOGGLE ; XOR (addr) with byte - .WORD C_HERE ; Dictionary pointer onto stack - .WORD C_1 ; Put 1 on stack - .WORD C_MINUS - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD $0080 - .WORD C_TOGGLE ; XOR (addr) with byte - .WORD C_LATEST ; Push top words NFA - .WORD C_COMMA ; Reserve 2 bytes and save n - .WORD C_CURRENT - .WORD C_FETCH ; Get word from addr on stack - .WORD C_STORE ; Store word at addr - .WORD C_HERE ; Dictionary pointer onto stack - .WORD C_2PLUS ; 2 plus - .WORD C_COMMA ; Reserve 2 bytes and save n - .WORD C_STOP ; Pop BC from return stack (=next) - -W_CCOMPILE: - .BYTE $89,"[COMPILE",']'+$80 - .WORD W_ID -C_CCOMPILE: - .WORD E_COLON ; Interpret following word sequence - .WORD C_MFIND - .WORD C_0EQUALS ; =0 - .WORD C_ZERO ; Put zero on stack - .WORD C_QERROR - .WORD C_DROP ; Drop top value from stack - .WORD C_CFA ; Convert PFA to CFA - .WORD C_COMMA ; Reserve 2 bytes and save n - .WORD C_STOP ; Pop BC from return stack (=next) - -W_LITERAL: - .BYTE $C7,"LITERA",'L'+$80 - .WORD W_CCOMPILE -C_LITERAL: - .WORD E_COLON ; Interpret following word sequence - .WORD C_STATE ; Push STATE addr - .WORD C_FETCH ; Get word from addr on stack - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B0022-$ ; 0008h - .WORD C_COMPILE ; Compile next word into dictionary - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD C_COMMA ; Reserve 2 bytes and save n -B0022: - .WORD C_STOP ; Pop BC from return stack (=next) - -W_DLITERAL: - .BYTE $C8,"DLITERA",'L'+$80 - .WORD W_LITERAL -C_DLITERAL: - .WORD E_COLON ; Interpret following word sequence - .WORD C_STATE ; Push STATE addr - .WORD C_FETCH ; Get word from addr on stack - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B0023-$ ; 0008h - .WORD C_SWAP ; Swap top 2 values on stack - .WORD C_LITERAL - .WORD C_LITERAL -B0023: - .WORD C_STOP ; Pop BC from return stack (=next) - -W_QSTACK: - .BYTE $86,"?STAC",'K'+$80 - .WORD W_DLITERAL -C_QSTACK: - .WORD E_COLON ; Interpret following word sequence - .WORD C_SPFETCH ; Stack pointer onto stack - .WORD C_S0 ; Push S0 (initial data stack pointer) - .WORD C_FETCH ; Get word from addr on stack - .WORD C_SWAP ; Swap top 2 values on stack - .WORD C_ULESS ; IF stack-1 < stack_top leave true flag - .WORD C_1 ; Put 1 on stack - .WORD C_QERROR - .WORD C_SPFETCH ; Stack pointer onto stack - .WORD C_HERE ; Dictionary pointer onto stack - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD $0080 - .WORD C_PLUS ; n1 + n2 - .WORD C_ULESS ; IF stack-1 < stack_top leave true flag - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD $0007 - .WORD C_QERROR - .WORD C_STOP ; Pop BC from return stack (=next) - -W_INTERPRET: - .BYTE $89,"INTERPRE",'T'+$80 - .WORD W_QSTACK -C_INTERPRET: - .WORD E_COLON ; Interpret following word sequence -B002A: - .WORD C_MFIND ; Find name returns PFA,length,true or false - .WORD C_0BRANCH ; Branch if name not found - .WORD NO_NAME-$ - .WORD C_STATE ; STATE addr on stack - .WORD C_FETCH ; Get STATE - .WORD C_LESSTHAN ; Is it quit compile word ? - .WORD C_0BRANCH ; If so then branch - .WORD B0025-$ ; - .WORD C_CFA ; Convert PFA to CFA - .WORD C_COMMA ; Reserve 2 bytes and save n - .WORD C_BRANCH ; Add following offset to BC - .WORD B0026-$ ; -B0025: - .WORD C_CFA ; Convert PFA to CFA - .WORD C_EXECUTE ; Jump to address on stack -B0026: - .WORD C_QSTACK ; Error message if stack underflow - .WORD C_BRANCH ; Add following offset to BC - .WORD B0027-$ ; -NO_NAME: - .WORD C_HERE ; Dictionary pointer onto stack - .WORD C_NUMBER ; Convert string at addr to double - .WORD C_DPL ; - .WORD C_FETCH ; Get word from addr on stack - .WORD C_1PLUS ; 1 plus - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B0028-$ ; - .WORD C_DLITERAL - .WORD C_BRANCH ; Add following offset to BC - .WORD B0029-$ ; -B0028: - .WORD C_DROP ; Drop top value from stack - .WORD C_LITERAL -B0029: - .WORD C_QSTACK ; Error message if stack underflow -B0027: - .WORD C_BRANCH ; Add following offset to BC - .WORD B002A-$ ; FF$C2 - -W_IMMEDIATE: - .BYTE $89,"IMMEDIAT",'E'+$80 - .WORD W_INTERPRET -C_IMMEDIATE: - .WORD E_COLON ; Interpret following word sequence - .WORD C_LATEST ; Push top words NFA - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD $0040 - .WORD C_TOGGLE ; XOR (addr) with byte - .WORD C_STOP ; Pop BC from return stack (=next) - -W_VOCABULARY: - .BYTE 8Ah,"VOCABULAR",'Y'+$80 - .WORD W_IMMEDIATE -C_VOCABULARY: - .WORD E_COLON ; Interpret following word sequence - .WORD C_CREATE - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD $A081 - .WORD C_COMMA ; Reserve 2 bytes and save n - .WORD C_CURRENT - .WORD C_FETCH ; Get word from addr on stack - .WORD C_CFA ; Convert PFA to CFA - .WORD C_COMMA ; Reserve 2 bytes and save n - .WORD C_HERE ; Dictionary pointer onto stack - .WORD C_VOC_LINK - .WORD C_FETCH ; Get word from addr on stack - .WORD C_COMMA ; Reserve 2 bytes and save n - .WORD C_VOC_LINK - .WORD C_STORE ; Store word at addr - .WORD C_DOES - .WORD C_2PLUS ; 2 plus - .WORD C_CONTEXT - .WORD C_STORE ; Store word at addr - .WORD C_STOP ; Pop BC from return stack (=next) - -C_LINK: - .WORD C_2PLUS ; 2 plus - .WORD C_FETCH ; Get word from addr on stack - .WORD C_CONTEXT - .WORD C_STORE ; Store word at addr - .WORD C_STOP ; Pop BC from return stack (=next) - -W_FORTH: - .BYTE $C5,"FORT",'H'+$80 - .WORD W_VOCABULARY -C_FORTH: - .WORD X_DOES - .WORD C_LINK - - .BYTE $81,' '+$80 - .WORD FLAST+2 -E_FORTH: - .WORD $0000 - -W_DEFINITIONS: ; Set CURRENT as CONTEXT vocabulary - .BYTE 8Bh,"DEFINITION",'S'+$80 - .WORD W_FORTH -C_DEFINITIONS: - .WORD E_COLON ; Interpret following word sequence - .WORD C_CONTEXT ; Get CONTEXT addr - .WORD C_FETCH ; Get word from addr on stack - .WORD C_CURRENT ; Get CURRENT addr - .WORD C_STORE ; Set CURRENT as the context vocabulary - .WORD C_STOP ; Pop BC from return stack (=next) - -W_OPENBRKT: - .BYTE $C1,'('+$80 - .WORD W_DEFINITIONS -C_OPENBRKT: - .WORD E_COLON ; Interpret following word sequence - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD $0029 - .WORD C_WORD - .WORD C_DROP ; Drop top value from stack - .WORD C_STOP ; Pop BC from return stack (=next) -;--------------------------------------------------------------------------------------- -; This it the last thing ever executed and is the interpreter -; outer loop. This NEVER quits. -;--------------------------------------------------------------------------------------- -W_QUIT: .BYTE $84,"QUI",'T'+$80 - .WORD W_OPENBRKT -C_QUIT: - .WORD E_COLON ; Interpret following word sequence - .WORD C_ZERO ; Put zero on stack - .WORD C_BLK ; Get current BLK pointer - .WORD C_STORE ; Set BLK to 0 - .WORD C_LEFTBRKT ; Set STATE to execute -B002C: - .WORD C_RPSTORE ; Set initial return stack pointer - .WORD C_CR ; Output [CR][LF] - .WORD C_QUERY ; Get string from input, ends in CR - .WORD C_INTERPRET ; Interpret input stream - .WORD C_STATE ; Push STATE addr - .WORD C_FETCH ; Get word from addr on stack - .WORD C_0EQUALS ; =0 - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD S_END8-$ ; 0007h - .WORD C_CQUOTE ; Output following string - .BYTE S_END8-S_START8 -S_START8: - .BYTE "OK" -S_END8: - .WORD C_BRANCH ; Add following offset to BC - .WORD B002C-$ ; FFE7h - -W_ABORT: - .BYTE $85,"ABOR",'T'+$80 - .WORD W_QUIT -C_ABORT: - .WORD E_COLON ; Interpret following word sequence - .WORD C_UABORT ; Put UABORT on stack - .WORD C_FETCH ; Get word from addr on stack - .WORD C_EXECUTE ; Jump to address on stack - .WORD C_STOP ; Pop BC from return stack (=next) - -CF_UABORT: - .WORD E_COLON ; Interpret following word sequence - .WORD C_SPSTORE ; Set initial stack pointer value - .WORD C_DECIMAL ; Sets decimal mode - .WORD C_QSTACK ; Error message if stack underflow - .WORD C_CR ; Output [CR][LF] - .WORD C_CQUOTE ; Output following string - .BYTE S_END1-S_START1 ; String length -S_START1: - .BYTE "* Z80 FORTH *" -S_END1: - .WORD C_FORTH - .WORD C_DEFINITIONS ; Set CURRENT as CONTEXT vocabulary - .WORD C_QUIT - -W_WARM: - .BYTE $84,"WAR",'M'+$80 - .WORD W_ABORT -C_WARM: - .WORD E_COLON ; Interpret following word sequence - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD WORD1 ; Start of detault table - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD S0 ; S0 addr - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD START_TABLE-WORD1 ; (000Ch) Table length - .WORD C_CMOVE ; Move block - .WORD C_ABORT - -X_COLD: - LD HL,START_TABLE ; Copy table to ram - LD DE,FLAST ; Where the table's going - LD BC,NEXTS2-START_TABLE ; Bytes to copy - LDIR ; - LD HL,W_TASK ; Copy TASK to ram - LD DE,VOCAB_BASE ; Where it's going - LD BC,W_TASKEND-W_TASK ; Bytes to copy - LDIR ; - LD BC,FIRSTWORD ; BC to first forth word - LD HL,(WORD1) ; Get stack pointer - LD SP,HL ; Set it - JP NEXT - -FIRSTWORD: - .WORD C_COLD - -W_COLD: .BYTE $84,"COL",'D'+$80 - .WORD W_WARM - .WORD X_COLD -C_COLD: .WORD E_COLON ; Interpret following word sequence - .WORD C_EBUFFERS ; Clear pseudo disk buffer - .WORD C_ZERO ; Put zero on stack - .WORD C_OFFSET ; Put disk block offset on stack - .WORD C_STORE ; Clear disk block offset - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD WORD1 ; Start of default table - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD S0 ; S0 addr - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD START_TABLE-WORD1 ; Block length on stack (0010h) - .WORD C_CMOVE ; Move block - .WORD C_ABORT - -W_SINGTODUB: ; Change single number to double - .BYTE $84,"S->",'D'+$80 - .WORD W_COLD -C_SINGTODUB: - .WORD 2+$ ; Vector to code - POP DE ; Get number - LD HL,$0000 ; Assume +ve extend - LD A,D ; Check sign - AND $80 ; - JR Z,IS_POS ; Really +ve so jump - DEC HL ; Make -ve extension -IS_POS: - JP NEXTS2 ; Save both & NEXT - -W_PLUSMINUS: - .BYTE $82,"+",'-'+$80 - .WORD W_SINGTODUB -C_PLUSMINUS: - .WORD E_COLON ; Interpret following word sequence - .WORD C_0LESS ; Less than 0 - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B002D-$ ; 0004h - .WORD C_NEGATE ; Form 2s complement of n -B002D: - .WORD C_STOP ; Pop BC from return stack (=next) - -W_DPLUSMINUS: ; Add sign of n to double - .BYTE $83,"D+",'-'+$80 - .WORD W_PLUSMINUS -C_DPLUSMINUS: - .WORD E_COLON ; Interpret following word sequence - .WORD C_0LESS ; Less than 0 - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B002E-$ ; 0004h - .WORD C_DNEGATE -B002E: - .WORD C_STOP ; Pop BC from return stack (=next) - -W_ABS: - .BYTE $83,"AB",'S'+$80 - .WORD W_DPLUSMINUS -C_ABS: - .WORD E_COLON ; Interpret following word sequence - .WORD C_DUP ; Duplicate top value on stack - .WORD C_PLUSMINUS - .WORD C_STOP ; Pop BC from return stack (=next) - -W_DABS: - .BYTE $84,"DAB",'S'+$80 - .WORD W_ABS -C_DABS: - .WORD E_COLON ; Interpret following word sequence - .WORD C_DUP ; Duplicate top value on stack - .WORD C_DPLUSMINUS ; Add sign of n to double - .WORD C_STOP ; Pop BC from return stack (=next) - -W_MIN: - .BYTE $83,"MI",'N'+$80 - .WORD W_DABS -C_MIN: - .WORD E_COLON ; Interpret following word sequence - .WORD C_2DUP ; Dup top 2 values on stack - .WORD C_GREATER - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B002F-$ ; 0004h - .WORD C_SWAP ; Swap top 2 values on stack -B002F: - .WORD C_DROP ; Drop top value from stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_MAX: - .BYTE $83,"MA",'X'+$80 - .WORD W_MIN -C_MAX: - .WORD E_COLON ; Interpret following word sequence - .WORD C_2DUP ; Dup top 2 values on stack - .WORD C_LESSTHAN - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B0030-$ ; 0004h - .WORD C_SWAP ; Swap top 2 values on stack -B0030: - .WORD C_DROP ; Drop top value from stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_MTIMES: - .BYTE $82,"M",'*'+$80 - .WORD W_MAX -C_MTIMES: - .WORD E_COLON ; Interpret following word sequence - .WORD C_2DUP ; Dup top 2 values on stack - .WORD C_XOR ; Works out sign of result - .WORD C_MOVER ; Move value from data to return stack - .WORD C_ABS - .WORD C_SWAP ; Swap top 2 values on stack - .WORD C_ABS - .WORD C_USTAR - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_DPLUSMINUS ; Add sign of n to double - .WORD C_STOP ; Pop BC from return stack (=next) - -W_MDIV: - .BYTE $82,"M",'/'+$80 - .WORD W_MTIMES -C_MDIV: - .WORD E_COLON ; Interpret following word sequence - .WORD C_OVER ; Copy 2nd down to top of stack - .WORD C_MOVER ; Move value from data to return stack - .WORD C_MOVER ; Move value from data to return stack - .WORD C_DABS - .WORD C_RFETCH ; Return stack top to data stack - .WORD C_ABS - .WORD C_UMOD ; Unsigned divide & MOD - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_RFETCH ; Return stack top to data stack - .WORD C_XOR ; XOR - .WORD C_PLUSMINUS - .WORD C_SWAP ; Swap top 2 values on stack - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_PLUSMINUS - .WORD C_SWAP ; Swap top 2 values on stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_TIMES: - .BYTE $81,'*'+$80 - .WORD W_MDIV -C_TIMES: - .WORD E_COLON ; Interpret following word sequence - .WORD C_MTIMES - .WORD C_DROP ; Drop top value from stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_DIVMOD: - .BYTE $84,"/MO",'D'+$80 - .WORD W_TIMES -C_DIVMOD: - .WORD E_COLON ; Interpret following word sequence - .WORD C_MOVER ; Move value from data to return stack - .WORD C_SINGTODUB ; Change single number to double - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_MDIV - .WORD C_STOP ; Pop BC from return stack (=next) - -W_DIV: - .BYTE $81,'/'+$80 - .WORD W_DIVMOD -C_DIV: - .WORD E_COLON ; Interpret following word sequence - .WORD C_DIVMOD - .WORD C_SWAP ; Swap top 2 values on stack - .WORD C_DROP ; Drop top value from stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_MOD: - .BYTE $83,"MO",'D'+$80 - .WORD W_DIV -C_MOD: - .WORD E_COLON ; Interpret following word sequence - .WORD C_DIVMOD - .WORD C_DROP ; Drop top value from stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_TIMESDIVMOD: - .BYTE $85,"*/MO",'D'+$80 - .WORD W_MOD -C_TIMESDIVMOD: - .WORD E_COLON ; Interpret following word sequence - .WORD C_MOVER ; Move value from data to return stack - .WORD C_MTIMES - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_MDIV - .WORD C_STOP ; Pop BC from return stack (=next) - -W_TIMESDIV: - .BYTE $82,"*",'/'+$80 - .WORD W_TIMESDIVMOD -C_TIMESDIV: - .WORD E_COLON ; Interpret following word sequence - .WORD C_TIMESDIVMOD - .WORD C_SWAP ; Swap top 2 values on stack - .WORD C_DROP ; Drop top value from stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_MDIVMOD: - .BYTE $85,"M/MO",'D'+$80 - .WORD W_TIMESDIV -C_MDIVMOD: - .WORD E_COLON ; Interpret following word sequence - .WORD C_MOVER ; Move value from data to return stack - .WORD C_ZERO ; Put zero on stack - .WORD C_RFETCH ; Return stack top to data stack - .WORD C_UMOD ; Unsigned divide & MOD - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_SWAP ; Swap top 2 values on stack - .WORD C_MOVER ; Move value from data to return stack - .WORD C_UMOD ; Unsigned divide & MOD - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_CLINE: - .BYTE $86,"'+$80 - .WORD W_MDIVMOD -C_CLINE: - .WORD E_COLON ; Interpret following word sequence - .WORD C_MOVER ; Move value from data to return stack - .WORD C_CL ; Put characters/line on stack - .WORD C_BBUF ; Put bytes per block on stack - .WORD C_TIMESDIVMOD - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_BSCR ; Number of buffers per block on stack - .WORD C_TIMES - .WORD C_PLUS ; n1 + n2 - .WORD C_BLOCK - .WORD C_PLUS ; n1 + n2 - .WORD C_CL ; Put characters/line on stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_DOTLINE: - .BYTE $85,".LIN",'E'+$80 - .WORD W_CLINE -C_DOTLINE: - .WORD E_COLON ; Interpret following word sequence - .WORD C_CLINE - .WORD C_TRAILING - .WORD C_TYPE ; Output n bytes from addr - .WORD C_STOP ; Pop BC from return stack (=next) - -W_MESSAGE: - .BYTE $87,"MESSAG",'E'+$80 - .WORD W_DOTLINE -C_MESSAGE: - .WORD E_COLON ; Interpret following word sequence - .WORD C_WARNING ; Put WARNING addr on stack - .WORD C_FETCH ; Get WARNING value - .WORD C_0BRANCH ; If WARNING = 0 output MSG # n - .WORD B0031-$ ; 001Eh - .WORD C_QUERYDUP - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B0032-$ ; 0014h - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD $0004 - .WORD C_OFFSET ; Put disk block offset on stack - .WORD C_FETCH ; Get word from addr on stack - .WORD C_BSCR ; Number of buffers per block on stack - .WORD C_DIV - .WORD C_MINUS - .WORD C_DOTLINE ; Output line from screen - .WORD C_SPACE ; Output space - -B0032: .WORD C_BRANCH ; Add following offset to BC - .WORD B0033-$ ; 00$0D - -B0031: .WORD C_CQUOTE ; Output following string - .BYTE S_END2-S_START2 -S_START2: .BYTE "MSG # " -S_END2: .WORD C_DOT -B0033: .WORD C_STOP ; Pop BC from return stack (=next) - -W_PORTIN: ; Fetch data from port - .BYTE $82,"P",'@'+$80 - .WORD W_MESSAGE -C_PORTIN: - .WORD 2+$ ; Vector to code - POP DE ; Get port addr - LD HL,PAT+1 ; Save in port in code - LD (HL),E ; - CALL PAT ; Call port in routine - LD L,A ; Save result - LD H,$00 ; - JP NEXTS1 ; Save & NEXT - -W_PORTOUT: ; Save data to port - .BYTE $82,"P",'!'+$80 - .WORD W_PORTIN -C_PORTOUT: - .WORD 2+$ ; Vector to code - POP DE ; Get port addr - LD HL,PST+1 ; Save in port out code - LD (HL),E ; - POP HL ; - LD A,L ; Byte to A - CALL PST ; Call port out routine - JP NEXT - -W_USE: .BYTE $83,"US",'E'+$80 - .WORD W_PORTOUT -C_USE: .WORD X_USER ; Put next word on stack then do next - .WORD USE-SYSTEM - -W_PREV: .BYTE $84,"PRE",'V'+$80 - .WORD W_USE -C_PREV: .WORD X_USER ; Put next word on stack then do next - .WORD PREV-SYSTEM - -W_PLUSBUF: - .BYTE $84,"+BU",'F'+$80 - .WORD W_PREV -C_PLUSBUF: - .WORD NEXT - -W_UPDATE: - .BYTE $86,"UPDAT",'E'+$80 - .WORD W_PLUSBUF -C_UPDATE: - .WORD NEXT - -W_EBUFFERS: ; Clear pseudo disk buffer - .BYTE $8D,"EMPTY-BUFFER",'S'+$80 - .WORD W_UPDATE -C_EBUFFERS: - .WORD E_COLON ; Interpret following word sequence - .WORD C_FIRST ; Start of pseudo disk onto stack - .WORD C_LIMIT ; End of pseudo disk onto stack - .WORD C_OVER ; Start to top of stack - .WORD C_MINUS ; Work out buffer length - .WORD C_ERASE ; Fill addr & length from stack with 0 - .WORD C_STOP ; Pop BC from return stack (=next) - -W_BUFFER: - .BYTE $86,"BUFFE",'R'+$80 - .WORD W_EBUFFERS -C_BUFFER: - .WORD E_COLON ; Interpret following word sequence - .WORD C_BLOCK - .WORD C_STOP ; Pop BC from return stack (=next) - -W_BLOCK: ; Put address of block n (+ offset) on stack - .BYTE $85,"BLOC",'K'+$80 - .WORD W_BUFFER -C_BLOCK: - .WORD E_COLON ; Interpret following word sequence - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD DISK_END/BLOCK_SIZE-DISK_START/BLOCK_SIZE - ; Max number of blocks - .WORD C_MOD ; MOD to max number - .WORD C_OFFSET ; Put address of disk block offset on stack - .WORD C_FETCH ; Get disk block offset - .WORD C_PLUS ; Add offset to block # - .WORD C_BBUF ; Put bytes per block on stack - .WORD C_TIMES ; Bytes times block number - .WORD C_FIRST ; Put address of first block on stack - .WORD C_PLUS ; Add address of first to byte offset - .WORD C_STOP ; Pop BC from return stack (=next) - -W_RW: - .BYTE $83,"R/",'W'+$80 - .WORD W_BLOCK -C_RW: - .WORD E_COLON ; Interpret following word sequence - .WORD C_URW ; - .WORD C_FETCH ; Get word from addr on stack - .WORD C_EXECUTE ; Jump to address on stack - .WORD C_STOP ; Pop BC from return stack (=next) -CF_URW: - .WORD E_COLON ; Interpret following word sequence - .WORD C_DROP ; Drop top value from stack - .WORD C_DROP ; Drop top value from stack - .WORD C_DROP ; Drop top value from stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_FLUSH: - .BYTE $85,"FLUS",'H'+$80 - .WORD W_RW -C_FLUSH: - .WORD E_COLON ; Interpret following word sequence - .WORD C_STOP ; Pop BC from return stack (=next) - -W_DUMP: - .BYTE $84,"DUM",'P'+$80 - .WORD W_FLUSH -C_DUMP: - .WORD E_COLON ; Interpret following word sequence - .WORD C_ZERO ; Put zero on stack - .WORD C_LDO ; Put start & end loop values on RPP -B0051: - .WORD C_CR ; Output [CR][LF] - .WORD C_DUP ; Duplicate top value on stack - .WORD C_ZERO ; Put zero on stack - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 0005h - .WORD C_DDOTR - .WORD C_SPACE ; Output space - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 0004h - .WORD C_SWAP ; Swap top 2 values on stack - .WORD C_OVER ; Copy 2nd down to top of stack - .WORD C_ZERO ; Put zero on stack - .WORD C_LDO ; Put start & end loop values on RPP -B0050: - .WORD C_DUP ; Duplicate top value on stack - .WORD C_CFETCH ; Get byte from addr on stack - .WORD C_3 - .WORD C_DOTR - .WORD C_1PLUS ; 1 plus - .WORD C_LLOOP ; Increment loop & branch if not done - .WORD B0050-$ ; FFF4h - .WORD C_SWAP ; Swap top 2 values on stack - .WORD C_PLOOP ; Loop + stack & branch if not done - .WORD B0051-$ ; FFD4h - .WORD C_DROP ; Drop top value from stack - .WORD C_CR ; Output [CR][LF] - .WORD C_STOP ; Pop BC from return stack (=next) - -W_LOAD: - .BYTE $84,"LOA",'D'+$80 - .WORD W_DUMP -C_LOAD: - .WORD E_COLON ; Interpret following word sequence - .WORD C_BLK ; Get current block number (0 = keyboard) - .WORD C_FETCH ; Get word from addr on stack - .WORD C_MOVER ; Save it for now - .WORD C_TOIN ; Current input buffer offset - .WORD C_FETCH ; Get word from addr on stack - .WORD C_MOVER ; Save it for now - .WORD C_ZERO ; Put zero on stack - .WORD C_TOIN ; Current input buffer offset - .WORD C_STORE ; Set to zero - .WORD C_BSCR ; Number of buffers per block on stack - .WORD C_TIMES ; Multiply block to load by buffers/block - .WORD C_BLK ; Get BLK pointer - .WORD C_STORE ; Make load block current input stream - .WORD C_INTERPRET ; Interpret input stream - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_TOIN ; Current input buffer offset - .WORD C_STORE ; Store word at addr - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_BLK ; Current block - .WORD C_STORE ; Store word at addr - .WORD C_STOP ; Pop BC from return stack (=next) - -W_NEXTSCREEN: - .BYTE $C3,"--",'>'+$80 - .WORD W_LOAD -C_NEXTSCREEN: - .WORD E_COLON ; Interpret following word sequence - .WORD C_QLOADING - .WORD C_ZERO ; Put zero on stack - .WORD C_TOIN ; Current input buffer offset - .WORD C_STORE ; Store word at addr - .WORD C_BSCR ; Number of buffers per block on stack - .WORD C_BLK - .WORD C_FETCH ; Get word from addr on stack - .WORD C_OVER ; Copy 2nd down to top of stack - .WORD C_MOD - .WORD C_MINUS - .WORD C_BLK - .WORD C_PLUSSTORE ; Add n1 to addr - .WORD C_STOP ; Pop BC from return stack (=next) - -W_TICK: - .BYTE $81,$2C+$80 - .WORD W_NEXTSCREEN -C_TICK: - .WORD E_COLON ; Interpret following word sequence - .WORD C_MFIND ; Find name returns PFA,length,true or false - .WORD C_0EQUALS ; =0 - .WORD C_ZERO ; Put zero on stack - .WORD C_QERROR - .WORD C_DROP ; Drop top value from stack - .WORD C_LITERAL - .WORD C_STOP ; Pop BC from return stack (=next) - -W_FORGET: - .BYTE $86,"FORGE",'T'+$80 - .WORD W_TICK -C_FORGET: - .WORD E_COLON ; Interpret following word sequence - .WORD C_CURRENT - .WORD C_FETCH ; Get word from addr on stack - .WORD C_CONTEXT - .WORD C_FETCH ; Get word from addr on stack - .WORD C_MINUS - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 0018h - .WORD C_QERROR - .WORD C_TICK - .WORD C_DUP ; Duplicate top value on stack - .WORD C_FENCE - .WORD C_FETCH ; Get word from addr on stack - .WORD C_LESSTHAN - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 0015h - .WORD C_QERROR - .WORD C_DUP ; Duplicate top value on stack - .WORD C_NFA ; Convert PFA to NFA - .WORD C_DP ; Dictionary pointer addr on stack - .WORD C_STORE ; Store word at addr - .WORD C_LFA - .WORD C_FETCH ; Get word from addr on stack - .WORD C_CONTEXT - .WORD C_FETCH ; Get word from addr on stack - .WORD C_STORE ; Store word at addr - .WORD C_STOP ; Pop BC from return stack (=next) - -W_BACK: - .BYTE $84,"BAC",'K'+$80 - .WORD W_FORGET -C_BACK: - .WORD E_COLON ; Interpret following word sequence - .WORD C_HERE ; Dictionary pointer onto stack - .WORD C_MINUS - .WORD C_COMMA ; Reserve 2 bytes and save n - .WORD C_STOP ; Pop BC from return stack (=next) - -W_BEGIN: - .BYTE $C5,"BEGI",'N'+$80 - .WORD W_BACK -C_BEGIN: - .WORD E_COLON ; Interpret following word sequence - .WORD C_QCOMP ; Error if not in compile mode - .WORD C_HERE ; Dictionary pointer onto stack - .WORD C_1 ; Put 1 on stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_ENDIF: - .BYTE $C5,"ENDI",'F'+$80 - .WORD W_BEGIN -C_ENDIF: - .WORD E_COLON ; Interpret following word sequence - .WORD C_QCOMP ; Error if not in compile mode - .WORD C_2 - .WORD C_QPAIRS - .WORD C_HERE ; Dictionary pointer onto stack - .WORD C_OVER ; Copy 2nd down to top of stack - .WORD C_MINUS - .WORD C_SWAP ; Swap top 2 values on stack - .WORD C_STORE ; Store word at addr - .WORD C_STOP ; Pop BC from return stack (=next) - -W_THEN: - .BYTE $C4,"THE",'N'+$80 - .WORD W_ENDIF -C_THEN: - .WORD E_COLON ; Interpret following word sequence - .WORD C_ENDIF - .WORD C_STOP ; Pop BC from return stack (=next) - -W_DO: - .BYTE $C2,"D",'O'+$80 - .WORD W_THEN -C_DO: - .WORD E_COLON ; Interpret following word sequence - .WORD C_COMPILE ; Compile next word into dictionary - .WORD C_LDO ; Put start & end loop values on RPP - .WORD C_HERE ; Dictionary pointer onto stack - .WORD C_3 - .WORD C_STOP ; Pop BC from return stack (=next) - -W_LOOP: - .BYTE $C4,"LOO",'P'+$80 - .WORD W_DO -C_LOOP: - .WORD E_COLON ; Interpret following word sequence - .WORD C_3 - .WORD C_QPAIRS - .WORD C_COMPILE ; Compile next word into dictionary - .WORD C_LLOOP ; Increment loop & branch if not done - .WORD C_BACK - .WORD C_STOP ; Pop BC from return stack (=next) - -W_PLUSLOOP: - .BYTE $C5,"+LOO",'P'+$80 - .WORD W_LOOP -C_PLUSLOOP: - .WORD E_COLON ; Interpret following word sequence - .WORD C_3 - .WORD C_QPAIRS - .WORD C_COMPILE ; Compile next word into dictionary - .WORD C_PLOOP ; Loop + stack & branch if not done - .WORD C_BACK - .WORD C_STOP ; Pop BC from return stack (=next) - -W_UNTIL: - .BYTE $C5,"UNTI",'L'+$80 - .WORD W_PLUSLOOP -C_UNTIL: - .WORD E_COLON ; Interpret following word sequence - .WORD C_1 ; Put 1 on stack - .WORD C_QPAIRS - .WORD C_COMPILE ; Compile next word into dictionary - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD C_BACK - .WORD C_STOP ; Pop BC from return stack (=next) - -W_END: - .BYTE $C3,"EN",'D'+$80 - .WORD W_UNTIL -C_END: - .WORD E_COLON ; Interpret following word sequence - .WORD C_UNTIL - .WORD C_STOP ; Pop BC from return stack (=next) - -W_AGAIN: - .BYTE $C5,"AGAI",'N'+$80 - .WORD W_END -C_AGAIN: - .WORD E_COLON ; Interpret following word sequence - .WORD C_1 ; Put 1 on stack - .WORD C_QPAIRS - .WORD C_COMPILE ; Compile next word into dictionary - .WORD C_BRANCH ; Add following offset to BC - .WORD C_BACK - .WORD C_STOP ; Pop BC from return stack (=next) - -W_REPEAT: - .BYTE $C6,"REPEA",'T'+$80 - .WORD W_AGAIN -C_REPEAT: - .WORD E_COLON ; Interpret following word sequence - .WORD C_MOVER ; Move value from data to return stack - .WORD C_MOVER ; Move value from data to return stack - .WORD C_AGAIN - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_2 - .WORD C_MINUS - .WORD C_ENDIF - .WORD C_STOP ; Pop BC from return stack (=next) - -W_IF: - .BYTE $C2,"I",'F'+$80 - .WORD W_REPEAT -C_IF: - .WORD E_COLON ; Interpret following word sequence - .WORD C_COMPILE ; Compile next word into dictionary - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD C_HERE ; Dictionary pointer onto stack - .WORD C_ZERO ; Put zero on stack - .WORD C_COMMA ; Reserve 2 bytes and save n - .WORD C_2 - .WORD C_STOP ; Pop BC from return stack (=next) - -W_ELSE: - .BYTE $C4,"ELS",'E'+$80 - .WORD W_IF -C_ELSE: - .WORD E_COLON ; Interpret following word sequence - .WORD C_2 - .WORD C_QPAIRS - .WORD C_COMPILE ; Compile next word into dictionary - .WORD C_BRANCH ; Add following offset to BC - .WORD C_HERE ; Dictionary pointer onto stack - .WORD C_ZERO ; Put zero on stack - .WORD C_COMMA ; Reserve 2 bytes and save n - .WORD C_SWAP ; Swap top 2 values on stack - .WORD C_2 - .WORD C_ENDIF - .WORD C_2 - .WORD C_STOP ; Pop BC from return stack (=next) - -W_WHILE: .BYTE $C5,"WHIL",'E'+$80 - .WORD W_ELSE -C_WHILE: - .WORD E_COLON ; Interpret following word sequence - .WORD C_IF - .WORD C_2PLUS ; 2 plus - .WORD C_STOP ; Pop BC from return stack (=next) - -W_SPACES: - .BYTE $86,"SPACE",'S'+$80 - .WORD W_WHILE -C_SPACES: - .WORD E_COLON ; Interpret following word sequence - .WORD C_ZERO ; Put zero on stack - .WORD C_MAX - .WORD C_QUERYDUP - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B0034-$ ; 000Ch - .WORD C_ZERO ; Put zero on stack - .WORD C_LDO ; Put start & end loop values on RPP -B0035: .WORD C_SPACE ; Output space - .WORD C_LLOOP ; Increment loop & branch if not done - .WORD B0035-$ ; FFFCh -B0034: .WORD C_STOP ; Pop BC from return stack (=next) - -W_LESSHARP: - .BYTE $82,"<",'#'+$80 - .WORD W_SPACES -C_LESSHARP: - .WORD E_COLON ; Interpret following word sequence - .WORD C_PAD ; Save intermediate string address - .WORD C_HLD - .WORD C_STORE ; Store word at addr - .WORD C_STOP ; Pop BC from return stack (=next) - -W_SHARPGT: - .BYTE $82,"#",'>'+$80 - .WORD W_LESSHARP -C_SHARPGT: - .WORD E_COLON ; Interpret following word sequence - .WORD C_DROP ; Drop top value from stack - .WORD C_DROP ; Drop top value from stack - .WORD C_HLD - .WORD C_FETCH ; Get word from addr on stack - .WORD C_PAD ; Save intermediate string address - .WORD C_OVER ; Copy 2nd down to top of stack - .WORD C_MINUS - .WORD C_STOP ; Pop BC from return stack (=next) - -W_SIGN: - .BYTE $84,"SIG",'N'+$80 - .WORD W_SHARPGT -C_SIGN: - .WORD E_COLON ; Interpret following word sequence - .WORD C_ROT ; 3rd valu down to top of stack - .WORD C_0LESS ; Less than 0 - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B0036-$ ; 0008h - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 002Dh - .WORD C_HOLD -B0036: - .WORD C_STOP ; Pop BC from return stack (=next) - -W_SHARP: - .BYTE $81,'#'+$80 - .WORD W_SIGN -C_SHARP: - .WORD E_COLON ; Interpret following word sequence - .WORD C_BASE ; Put BASE addr on stack - .WORD C_FETCH ; Get word from addr on stack - .WORD C_MDIVMOD - .WORD C_ROT ; 3rd valu down to top of stack - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 0009h - .WORD C_OVER ; Copy 2nd down to top of stack - .WORD C_LESSTHAN - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B0037-$ ; 0008h - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 0007h - .WORD C_PLUS ; n1 + n2 -B0037: - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD $0030 - .WORD C_PLUS ; n1 + n2 - .WORD C_HOLD - .WORD C_STOP ; Pop BC from return stack (=next) - -W_SHARPS: - .BYTE $82,"#",'S'+$80 - .WORD W_SHARP -C_SHARPS: - .WORD E_COLON ; Interpret following word sequence -B0038: - .WORD C_SHARP - .WORD C_OVER ; Copy 2nd down to top of stack - .WORD C_OVER ; Copy 2nd down to top of stack - .WORD C_OR ; OR - .WORD C_0EQUALS ; =0 - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B0038-$ ; FFF4h - .WORD C_STOP ; Pop BC from return stack (=next) - -W_DDOTR: - .BYTE $83,"D.",'R'+$80 - .WORD W_SHARPS -C_DDOTR: - .WORD E_COLON ; Interpret following word sequence - .WORD C_MOVER ; Move value from data to return stack - .WORD C_SWAP ; Swap top 2 values on stack - .WORD C_OVER ; Copy 2nd down to top of stack - .WORD C_DABS - .WORD C_LESSHARP - .WORD C_SHARPS - .WORD C_SIGN - .WORD C_SHARPGT - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_OVER ; Copy 2nd down to top of stack - .WORD C_MINUS - .WORD C_SPACES - .WORD C_TYPE ; Output n bytes from addr - .WORD C_STOP ; Pop BC from return stack (=next) - -W_DOTR: - .BYTE $82,".",'R'+$80 - .WORD W_DDOTR -C_DOTR: - .WORD E_COLON ; Interpret following word sequence - .WORD C_MOVER ; Move value from data to return stack - .WORD C_SINGTODUB ; Change single number to double - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_DDOTR - .WORD C_STOP ; Pop BC from return stack (=next) - -W_DDOT: - .BYTE $82,"D",'.'+$80 - .WORD W_DOTR -C_DDOT: - .WORD E_COLON ; Interpret following word sequence - .WORD C_ZERO ; Put zero on stack - .WORD C_DDOTR - .WORD C_SPACE ; Output space - .WORD C_STOP ; Pop BC from return stack (=next) - -W_DOT: - .BYTE $81,'.'+$80 - .WORD W_DDOT -C_DOT: - .WORD E_COLON ; Interpret following word sequence - .WORD C_SINGTODUB ; Change single number to double - .WORD C_DDOT - .WORD C_STOP ; Pop BC from return stack (=next) - -W_QUESTION: - .BYTE $81,'?'+$80 - .WORD W_DOT -C_QUESTION: - .WORD E_COLON ; Interpret following word sequence - .WORD C_FETCH ; Get word from addr on stack - .WORD C_DOT - .WORD C_STOP ; Pop BC from return stack (=next) - -W_UDOT: ; Output as unsigned value - .BYTE $82,"U",'.'+$80 - .WORD W_QUESTION -C_UDOT: - .WORD E_COLON ; Interpret following word sequence - .WORD C_ZERO ; Put zero on stack - .WORD C_DDOT ; Output double value - .WORD C_STOP ; Pop BC from return stack (=next) - -W_VLIST: - .BYTE $85,"VLIS",'T'+$80 - .WORD W_UDOT -C_VLIST: - .WORD E_COLON ; Interpret following word sequence - .WORD C_CONTEXT ; Leave vocab pointer on stack - .WORD C_FETCH ; Get word from addr on stack - .WORD C_FETCH ; Get word from addr on stack - .WORD C_CR ; Output [CR][LF] -B0039: - .WORD C_DUP ; Duplicate top value on stack - .WORD C_PFA ; Convert NFA to PFA - .WORD C_SWAP ; Swap top 2 values on stack - .WORD C_ID ; Print definition name from name field addr - .WORD C_LFA ; Convert param addr to link addr - .WORD C_FETCH ; Get word from addr on stack - .WORD C_DUP ; Duplicate top value on stack - .WORD C_0EQUALS ; =0 - .WORD C_TERMINAL ; Check for break key - .WORD C_OR ; OR - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B0039-$ ; FFE2h - .WORD C_DROP ; Drop top value from stack - .WORD C_CR ; Output [CR][LF] - .WORD C_STOP ; Pop BC from return stack (=next) - -W_LIST: - .BYTE $84,"LIS",'T'+$80 - .WORD W_VLIST -C_LIST: - .WORD E_COLON ; Interpret following word sequence - .WORD C_BASE ; Put BASE addr on stack - .WORD C_FETCH ; Put current base on stack - .WORD C_SWAP ; Get number of list screen to top - .WORD C_DECIMAL ; Sets decimal mode - .WORD C_CR ; Output [CR][LF] - .WORD C_DUP ; Duplicate top value on stack - .WORD C_SCR ; Set most recently listed - .WORD C_STORE ; Store word at addr - .WORD C_CQUOTE ; Output following string - .BYTE S_END3-S_START3 -S_START3: - .BYTE "SCR # " -S_END3: - .WORD C_DOT ; Output the screen number - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD $0010 ; 16 lines to do - .WORD C_ZERO ; From 0 to 15 - .WORD C_LDO ; Put start & end loop values on RPP -DO_LINE: - .WORD C_CR ; Output [CR][LF] - .WORD C_I ; Line number onto data stack - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD $0003 ; Fromat right justified 3 characters - .WORD C_DOTR ; Output formatted - .WORD C_SPACE ; Output space - .WORD C_I ; Line number onto data stack - .WORD C_SCR ; Get screen number - .WORD C_FETCH ; Get word from addr on stack - .WORD C_DOTLINE ; Output line from screen - .WORD C_TERMINAL ; Check for break key - .WORD C_0BRANCH ; Jump if no break key - .WORD NO_BRK-$ - .WORD C_LEAVE ; Else set loop index to limit (quit loop) -NO_BRK: - .WORD C_LLOOP ; Increment loop & branch if not done - .WORD DO_LINE-$ - .WORD C_CR ; Output [CR][LF] - .WORD C_BASE ; Put BASE addr on stack - .WORD C_STORE ; Restore original base - .WORD C_STOP ; Pop BC from return stack (=next) - -W_INDEX: - .BYTE $85,"INDE",'X'+$80 - .WORD W_LIST -C_INDEX: - .WORD E_COLON ; Interpret following word sequence - .WORD C_1PLUS ; 1 plus - .WORD C_SWAP ; Swap top 2 values on stack - .WORD C_LDO ; Put start & end loop values on RPP -B003D: - .WORD C_CR ; Output [CR][LF] - .WORD C_I ; Copy LOOP index to data stack - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 0003h - .WORD C_DOTR - .WORD C_SPACE ; Output space - .WORD C_ZERO ; Put zero on stack - .WORD C_I ; Copy LOOP index to data stack - .WORD C_DOTLINE ; Output line from screen - .WORD C_TERMINAL ; Check for break key - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B003C-$ ; 0004h - .WORD C_LEAVE ; Quit loop by making index = limit -B003C: - .WORD C_LLOOP ; Increment loop & branch if not done - .WORD B003D-$ ; FFE4h - .WORD C_CR ; Output [CR][LF] - .WORD C_STOP ; Pop BC from return stack (=next) - -W_INT: - .BYTE $C4,"; IN",'T'+$80 - .WORD W_INDEX -C_INT: - .WORD E_COLON ; Interpret following word sequence - .WORD C_WHATSTACK ; Check stack pointer, error if not ok - .WORD C_COMPILE ; Compile next word into dictionary - .WORD X_INT - .WORD C_LEFTBRKT ; Set STATE to execute - .WORD C_SMUDGE - .WORD C_STOP ; Pop BC from return stack (=next) - -X_INT: - .WORD 2+$ ; Vector to code - LD HL,INTFLAG - RES 6,(HL) - EI - JP X_STOP - -W_INTFLAG: - .BYTE $87,"INTFLA",'G'+$80 - .WORD W_INT -C_INTFLAG: - .WORD X_USER ; Put next word on stack then do next - .WORD INTFLAG-SYSTEM - -W_INTVECT: - .BYTE $87,"INTVEC",'T'+$80 - .WORD W_INTFLAG -C_INTVECT: - .WORD X_USER ; Put next word on stack then do next - .WORD INTVECT-SYSTEM - -W_CPU: - .BYTE $84,".CP",'U'+$80 - .WORD W_INTVECT -C_CPU: - .WORD E_COLON ; Interpret following word sequence - .WORD C_CQUOTE ; Output following string - .BYTE S_END4-S_START4 -S_START4: - .BYTE "Z80 " -S_END4: - .WORD C_STOP ; Pop BC from return stack (=next) - -W_2SWAP: - .BYTE $85,"2SWA",'P'+$80 - .WORD W_CPU -C_2SWAP: - .WORD E_COLON ; Interpret following word sequence - .WORD C_ROT ; 3rd valu down to top of stack - .WORD C_MOVER ; Move value from data to return stack - .WORD C_ROT ; 3rd valu down to top of stack - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_2OVER: - .BYTE $85,"2OVE",'R'+$80 - .WORD W_2SWAP -C_2OVER: - .WORD E_COLON ; Interpret following word sequence - .WORD C_MOVER ; Move value from data to return stack - .WORD C_MOVER ; Move value from data to return stack - .WORD C_2DUP ; Dup top 2 values on stack - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_2SWAP - .WORD C_STOP ; Pop BC from return stack (=next) - -W_EXIT: - .BYTE $84,"EXI",'T'+$80 - .WORD W_2OVER -C_EXIT: - .WORD X_STOP - -W_J: ; Push outer loop value on stack - .BYTE $81,'J'+$80 - .WORD W_EXIT -C_J: - .WORD 2+$ ; Vector to code - LD HL,(RPP) ; Get return stack pointer - INC HL ; Skip inner loop values - INC HL ; - INC HL ; - INC HL ; - JP X_I2 - -W_ROLL: - .BYTE $84,"ROL",'L'+$80 - .WORD W_J -C_ROLL: - .WORD E_COLON ; Interpret following word sequence - .WORD C_DUP ; Duplicate top value on stack - .WORD C_ZERO ; Put zero on stack - .WORD C_GREATER - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B003E-$ ; 002Ch - .WORD C_DUP ; Duplicate top value on stack - .WORD C_MOVER ; Move value from data to return stack - .WORD C_PICK - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_ZERO ; Put zero on stack - .WORD C_SWAP ; Swap top 2 values on stack - .WORD C_LDO ; Put start & end loop values on RPP -B003F: - .WORD C_SPFETCH ; Stack pointer onto stack - .WORD C_I ; Copy LOOP index to data stack - .WORD C_DUP ; Duplicate top value on stack - .WORD C_PLUS ; n1 + n2 - .WORD C_PLUS ; n1 + n2 - .WORD C_DUP ; Duplicate top value on stack - .WORD C_2MINUS ; 2 minus - .WORD C_FETCH ; Get word from addr on stack - .WORD C_SWAP ; Swap top 2 values on stack - .WORD C_STORE ; Store word at addr - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD $FFFF - .WORD C_PLOOP ; Loop + stack & branch if not done - .WORD B003F-$ ; FFE6h -B003E: - .WORD C_DROP ; Drop top value from stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_DEPTH: - .BYTE $85,"DEPT",'H'+$80 - .WORD W_ROLL -C_DEPTH: - .WORD E_COLON ; Interpret following word sequence - .WORD C_S0 ; Push S0 (initial data stack pointer) - .WORD C_FETCH ; Get word from addr on stack - .WORD C_SPFETCH ; Stack pointer onto stack - .WORD C_MINUS - .WORD C_2 - .WORD C_DIV - .WORD C_1MINUS ; 1 minus - .WORD C_STOP ; Pop BC from return stack (=next) - -W_DLESSTHAN: - .BYTE $82,"D",'<'+$80 - .WORD W_DEPTH -C_DLESSTHAN: - .WORD E_COLON ; Interpret following word sequence - .WORD C_ROT ; 3rd valu down to top of stack - .WORD C_2DUP ; Dup top 2 values on stack - .WORD C_EQUALS - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B0040-$ ; 00$0A - .WORD C_2DROP ; Drop top two values from stack - .WORD C_ULESS ; IF stack-1 < stack_top leave true flag - .WORD C_BRANCH ; Add following offset to BC - .WORD B0041-$ ; 0008h -B0040: - .WORD C_2SWAP - .WORD C_2DROP ; Drop top two values from stack - .WORD C_GREATER -B0041: - .WORD C_STOP ; Pop BC from return stack (=next) - -W_0GREATER: - .BYTE $82,"0",'>'+$80 - .WORD W_DLESSTHAN -C_0GREATER: - .WORD E_COLON ; Interpret following word sequence - .WORD C_ZERO ; Put zero on stack - .WORD C_GREATER - .WORD C_STOP ; Pop BC from return stack (=next) - -W_DOTS: - .BYTE $82,".",'S'+$80 - .WORD W_0GREATER -C_DOTS - .WORD E_COLON ; Interpret following word sequence - .WORD C_CR ; Output [CR][LF] - .WORD C_DEPTH - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B0042-$ ; 0020h - .WORD C_SPFETCH ; Stack pointer onto stack - .WORD C_2MINUS ; 2 minus - .WORD C_S0 ; Push S0 (initial data stack pointer) - .WORD C_FETCH ; Get word from addr on stack - .WORD C_2MINUS ; 2 minus - .WORD C_LDO ; Put start & end loop values on RPP -B0043: - .WORD C_I ; Copy LOOP index to data stack - .WORD C_FETCH ; Get word from addr on stack - .WORD C_DOT - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD $FFFE - .WORD C_PLOOP ; Loop + stack & branch if not done - .WORD B0043-$ ; FFF4h - .WORD C_BRANCH ; Add following offset to BC - .WORD S_END5-$ ; 0011h -B0042: - .WORD C_CQUOTE ; Output following string - .BYTE S_END5-S_START5 -S_START5: - .BYTE "STACK EMPTY " -S_END5: - .WORD C_STOP ; Pop BC from return stack (=next) - -W_CODE: - .BYTE $84,"COD",'E'+$80 - .WORD W_DOTS -C_CODE: - .WORD E_COLON ; Interpret following word sequence - .WORD C_QEXEC ; Error not if not in execute mode - .WORD C_XXX1 - .WORD C_SPSTORE ; Set initial stack pointer value - .WORD C_STOP ; Pop BC from return stack (=next) - -W_ENDCODE: - .BYTE $88,"END-COD",'E'+$80 - .WORD W_CODE -C_ENDCODE: - .WORD E_COLON ; Interpret following word sequence - .WORD C_CURRENT - .WORD C_FETCH ; Get word from addr on stack - .WORD C_CONTEXT - .WORD C_STORE ; Store word at addr - .WORD C_QEXEC ; Error not if not in execute mode - .WORD C_WHATSTACK ; Check stack pointer, error if not ok - .WORD C_SMUDGE - .WORD C_STOP ; Pop BC from return stack (=next) - -W_NEXT: - .BYTE $C4,"NEX",'T'+$80 - .WORD W_ENDCODE -C_NEXT: - .WORD E_COLON ; Interpret following word sequence - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD $00C3 ; Jump instruction - .WORD C_CCOMMA ; Save as 8 bit value - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD NEXT ; The address of NEXT - .WORD C_COMMA ; Reserve 2 bytes and save n - .WORD C_STOP ; Pop BC from return stack (=next) - -W_IM2: ; Set interrupt mode 2 - .BYTE $83,"IM",'2'+$80 - .WORD W_NEXT -C_IM2: - .WORD 2+$ ; Vector to code - IM 2 ; Mode 2 - JP NEXT - -W_IM1: ; Set interrupt mode 1 - .BYTE $83,"IM",'1'+$80 - .WORD W_IM2 -C_IM1: - .WORD 2+$ ; Vector to code - IM 1 ; Mode 1 - JP NEXT - -W_IM0: ; Set interrupt mode 0 - .BYTE $83,"IM",'0'+$80 - .WORD W_IM1 -C_IM0: - .WORD 2+$ ; Vector to code - IM 0 ; Mode 0 - JP NEXT - -W_DI: ; Disable interrupt - .BYTE $82,"D",'I'+$80 - .WORD W_IM0 -C_DI: - .WORD 2+$ ; Vector to code - DI ; Disable interrupt - JP NEXT - -W_EI: ; Enable interrupt - .BYTE $82,"E",'I'+$80 - .WORD W_DI -C_EI: - .WORD 2+$ ; Vector to code - EI ; Enable interrupt - JP NEXT - -W_MON: ; Jump to m/c monitor - .BYTE $83,"MO",'N'+$80 - .WORD W_EI -C_MON: - .WORD 2+$ - JP MONSTART - -W_LLOAD: - .BYTE $85,"LLOA",'D'+$80 - .WORD W_MON -C_LLOAD: - .WORD E_COLON ; Interpret following word sequence - .WORD C_BLOCK ; Get block address - .WORD C_LIT ; Enter loop with null - .WORD $0000 ; -LL_BEGIN: - .WORD C_DUP ; Dup key - .WORD C_0BRANCH ; If null then don't store - .WORD LL_NULL-$ - .WORD C_DUP ; Dup key again - .WORD C_LIT ; Compare to [CR] - .WORD $000D ; - .WORD C_EQUALS - .WORD C_0BRANCH ; If not [CR] then jump - .WORD LL_STORE-$ ; - .WORD C_DROP ; Drop the [CR] - .WORD C_CL ; Get characters per line - .WORD C_PLUS ; Add to current addr - .WORD C_CL ; Make CL MOD value - .WORD C_NEGATE ; Form 2s complement of n - .WORD C_AND ; Mask out bits - .WORD C_BRANCH ; Done this bit so jump - .WORD NO_STORE-$ -LL_STORE: - .WORD C_OVER ; Get address to store at - .WORD C_STORE ; Save chr -NO_STORE: - .WORD C_1PLUS ; Next addres - .WORD C_BRANCH ; Done so jump - .WORD LL_CHAR-$ -LL_NULL: - .WORD C_DROP ; Was null so drop it -LL_CHAR: - .WORD C_KEY ; Get key - .WORD C_DUP ; Duplicate it - .WORD C_LIT ; Compare with [CTRL] Z - .WORD $001A - .WORD C_EQUALS - .WORD C_0BRANCH ; If not EOF then jump - .WORD LL_BEGIN-$ ; - .WORD C_DROP ; Drop EOF character - .WORD C_DROP ; Drop next address - .WORD C_STOP ; Pop BC from return stack (=next) - -W_TASK: - .BYTE $84,"TAS",'K'+$80 - .WORD W_LLOAD -C_TASK: - .WORD E_COLON ; Interpret following word sequence - .WORD C_STOP ; Pop BC from return stack (=next) -W_TASKEND: - -W_EDITI: - -W_CLEAR: ; Clear block n - .BYTE $85,"CLEA",'R'+$80 - .WORD W_TASK -C_CLEAR: - .WORD E_COLON ; Interpret following word sequence - .WORD C_DUP ; Duplicate number - .WORD C_SCR ; Get SCR addr - .WORD C_STORE ; Store screen number - .WORD C_BLOCK ; Get the address of the block - .WORD C_BBUF ; Put number of bytes/block on stack - .WORD C_ERASE ; Clear the block - .WORD C_STOP ; Pop BC from return stack (=next) - -CF_UKEY: ; Get key onto stack - .WORD 2+$ ; Vector to code - CALL CHR_RD ; User key in routine - LD L,A ; Put key on stack - LD H,$00 ; - JP NEXTS1 ; Save & NEXT - -CF_UEMIT: ; Chr from stack to output - .WORD 2+$ ; Vector to code - POP HL ; Get CHR to output - LD A,L ; Put in A - PUSH BC ; Save regs - PUSH DE ; - CALL CHR_WR ; User output routine - POP DE ; Restore regs - POP BC ; - JP NEXT ; - -CF_UCR: ; CR output - .WORD 2+$ ; Vector to code - PUSH BC ; Save regs - PUSH DE ; Just in case - LD A,$0D ; Carrage return - CALL CHR_WR ; User output routine - LD A,$0A ; Line feed - CALL CHR_WR ; User output routine - POP DE ; Get regs back - POP BC ; - JP NEXT ; Next - -CF_UQTERMINAL: ; Test for user break - .WORD 2+$ ; Vector to code - PUSH BC ; Save regs - PUSH DE ; Just in case - CALL BREAKKEY ; User break test routine - POP DE ; Get regs back - POP BC ; - LD H,$00 ; Clear H - LD L,A ; Result in L - JP NEXTS1 ; Store it & Next - -;------------------------------------------------------------------------------ -; SERIAL I/O ROUTINES -; Change these to suit your target system ..... -;------------------------------------------------------------------------------ -;------------------------------------------------------------------------------ -; RXA - Receive a byte over SIO/0 Ch A -;------------------------------------------------------------------------------ -RXA CALL CKSIOA ; Get the status word - JR NC,RXA ; Loop until a character arrives - IN A,($74) ; Get the character - RET ; Char ready in A -;------------------------------------------------------------------------------ -; TXA - Transmit a byte over SIO/0 Ch A -;------------------------------------------------------------------------------ -TXA PUSH AF ; Store character - CALL CKSIOA ; See if SIO channel A is finished transmitting - JR Z,TXA+1 ; Loop until SIO flag signals ready - POP AF ; Retrieve character - OUT ($74),A ; Output the character - RET -;------------------------------------------------------------------------------ -; Check SIO Channel A status flag, RX char ready=CY, TX buffer clear=NZ -;------------------------------------------------------------------------------ -CKSIOA XOR A ; Zeroize A - OUT ($76),A ; Select Register 0 - IN A,($76) ; Retrieve Status Word - RRCA ; RX status into CY flag - BIT 1,A ; TX Buffer Empty into Z flag - RET -;------------------------------------------------------------------------------ -CHR_RD: CALL RXA ; GET A CHARACTER - CP $61 ; Is UCASE already? - JR C,CHR_RD1 ; It is, leave it alone - CP $7A ; <= "z" ? - JR NC,CHR_RD1 ; - AND $5F ; It's A-Z, or a-z make it upper case -CHR_RD1 RET - -NO_BUF_KEY: - JP RXA ; GET A CHARACTER - -BREAKKEY: CALL CKSIOA ; CHECK USART - JR NC,NO_KEY ; NOTHING - IN A,($74) ; READ THE CHARACTER - CP $03 ; BREAK? - JR Z,WAS_BRK ; YES - CP $61 ; Is UCASE already? - JR C,BRK01 ; It is, leave it alone - CP $7A ; <= "z" ? - JR NC,BRK01 - AND $5F ; It's A-Z, or a-z make it upper case -BRK01 RET ; ELSE RETURN WITH KEY - -NO_KEY: XOR A ; Wasn't break, or no key, so clear - RET - -WAS_BRK: LD A,$01 ; Was break so set flag - RET - -CHR_WR: RST 08H ; WRITE CHARACTER - RET -;------------------------------------------------------------------------------ -FINIS .END diff --git a/doug/src/baseline.arf b/doug/src/baseline.arf deleted file mode 100755 index d276c14d..00000000 --- a/doug/src/baseline.arf +++ /dev/null @@ -1,17 +0,0 @@ --mjx --i baseline.ihx --k /usr/local/share/sdcc/lib/z80 --l z80 --b _CCPB03 = 0xD000 --b _BDOSB01 = 0xD800 --b _CBIOS = 0xE600 --b _DBGMON = 0x8000 -crt0.rel -baseline.rel -ns16550.rel -i8255.rel -dbgmon.rel -ccpb03.rel -bdosb01.rel -cbios.rel --e diff --git a/doug/src/baseline.c b/doug/src/baseline.c deleted file mode 100755 index 69260939..00000000 --- a/doug/src/baseline.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * baseline.c - Diagnostic EPROM for the N8VEM SBC V2 - * - */ - -#include -#include -#include -#include "portab.h" -#include "sbcv2.h" -#include "ns16550.h" - -/* #include "cpmbdos.h" */ - -/* THESE ARE USED BY THE LIBRARY ROUTINES */ -char getchar(void) -{ -/* - struct BDOSCALL cread = { C_READ, { (unsigned int)0 } }; - return cpmbdos(&cread); -*/ - return 0; -} -void outchar(char c) -{ - if(c) ; -/* - struct BDOSCALL cwrite = { C_WRITE, { (unsigned int)c } }; - cpmbdos(&cwrite); -*/ -} - - -void xdisable(void) -{ -} - -void xenable(void) -{ -} - -void intmode(U8 xmode) -{ - if(xmode); -} - -int main(void) -{ - pMPCL_ROM = 0x80; - pMPCL_RAM = 0x81; - - memcpy(0,0x0E5,0x2000); - - pMPCL_ROM = 0x80; - pMPCL_RAM = 0x00; - - xdisable(); - intmode(1); - pMPCL_ROM = 0x00; - pMPCL_RAM = 0x00; - - memcpy(RAMTARG_CPM,ROMSTART_CPM,CCPSIZ_CPM); - - pMPCL_ROM = 0x80; - pMPCL_RAM = 0x00; - return (0); -} - diff --git a/doug/src/bdosb01.arf b/doug/src/bdosb01.arf deleted file mode 100755 index 7c5391de..00000000 --- a/doug/src/bdosb01.arf +++ /dev/null @@ -1,6 +0,0 @@ --mjx --i bdosb01.ihx --k /usr/local/share/sdcc/lib/z80 --l z80 -bdosb01.rel --e diff --git a/doug/src/bdosb01.lst b/doug/src/bdosb01.lst deleted file mode 100755 index f2388aa7..00000000 --- a/doug/src/bdosb01.lst +++ /dev/null @@ -1,2675 +0,0 @@ - 1 .title bdosb01.s derived from bdosb01.asm - 2 .sbttl by Douglas Goodall for N8VEM use '11 - 3 - 4 .module bdosb01 - 5 .optsdcc -mz80 - 6 - 7 ;-------------------------------------------------------- - 8 ; Public variables in this module - 9 ;-------------------------------------------------------- - 10 .globl _bdos - 11 ;-------------------------------------------------------- - 12 ; special function registers - 13 ;-------------------------------------------------------- - 14 ;-------------------------------------------------------- - 15 ; ram data - 16 ;-------------------------------------------------------- - 17 .area _DATA - 18 ;-------------------------------------------------------- - 19 ; overlayable items in ram - 20 ;-------------------------------------------------------- - 21 .area _OVERLAY - 22 ;-------------------------------------------------------- - 23 ; external initialized ram data - 24 ;-------------------------------------------------------- - 25 ;-------------------------------------------------------- - 26 ; global & static initialisations - 27 ;-------------------------------------------------------- - 28 .area _HOME - 29 .area _GSINIT - 30 .area _GSFINAL - 31 .area _GSINIT - 32 ;-------------------------------------------------------- - 33 ; Home - 34 ;-------------------------------------------------------- - 35 .area _HOME - 36 .area _HOME - 37 ;-------------------------------------------------------- - 38 ; code - 39 ;-------------------------------------------------------- - 40 .area _CODE - 41 ;bdos.c:1: void bdos(void) - 42 ; --------------------------------- - 43 ; Function bdos - 44 ; --------------------------------- - 0000 45 _bdos_start:: - 0000 46 _bdos: - 47 - 48 ;dwg-start; - 49 .area _DATA - 50 ;dwg-end; - 51 - 0001 52 ENDFIL = 1 ;FILL FULL BDOS LENGTH - 53 ; - 0003 54 IOBYTE = 3 ; I/O DEFINITION BYTE. - 0004 55 TDRIVE = 4 ; CURRENT DRIVE NAME AND USER NUMBER. - 0005 56 ENTRY = 5 ; ENTRY POINT FOR THE CP/M BDOS. - 005C 57 TFCB = 0x5C ; DEFAULT FILE CONTROL BLOCK. - 0080 58 TBUFF = 0x80 ; I/O BUFFER AND COMMAND LINE STORAGE. - 0100 59 TBASE = 0x100 ; TRANSIANT PROGRAM STORAGE AREA. - 60 ; - 61 ; SET CONTROL CHARACTER .EQUATES. - 62 ; - 0041 63 ASCIIA = 0x41 - 0040 64 AT = 0x40 - 0003 65 CNTRLC = 3 ; CONTROL-C - 0005 66 CNTRLE = 05 ; CONTROL-E - 0008 67 BS = 08 ; BACKSPACE - 0009 68 TAB = 09 ; TAB - 000A 69 LF = 0x0A ; LINE FEED - 000C 70 FF = 0x0C ; FORM FEED - 000D 71 CR = 0x0D ; CARRIAGE RETURN - 0010 72 CNTRLP = 0x10 ; CONTROL-P - 0012 73 CNTRLR = 0x12 ; CONTROL-R - 0013 74 CNTRLS = 0x13 ; CONTROL-S - 0015 75 CNTRLU = 0x15 ; CONTROL-U - 0018 76 CNTRLX = 0x18 ; CONTROL-X - 001A 77 CNTRLZ = 0x1A ; CONTROL-Z (END-OF-FILE MARK) - 0020 78 SPACE = 0x20 - 0023 79 POUND = 0x23 - 0024 80 DOLLAR = 0x24 - 003F 81 QUESTION = 0x3f - 005E 82 UP = 0x5E - 007F 83 DEL = 0x7F ; RUBOUT - 84 - 85 ; CPM ORIGIN CALCULATE - 86 - 003B 87 NK = 59 ;SYSTEM SIZE - 9C00 88 BASE = (NK*1024)-0x5000 - D000 89 CCPO = BASE+0x3400 ;CCP ORIGIN - D800 90 BDOSO = BASE+0x3C00 ;BDOS ORIGIN - E600 91 BIOSO = BASE+0x4A00 ;BIOS ORIGIN - 92 - 93 ;dwg-begin; - 94 - 95 ; .area _CODE - 96 .area _BDOSB01 - 97 - 98 ;dwg-end; - 99 - 100 ;dwg; .ORG BDOSO - 0000 00 00 00 00 00 00 101 .DB 0,0,0,0,0,0 ;OLD SERIAL NUMBER - 102 ; - 103 ;************************************************************** - 104 ;* - 105 ;* B D O S E N T R Y - 106 ;* - 107 ;************************************************************** - 108 ; - 0006 C3r11s00 109 FBASE: JP FBASE1 - 110 ; - 111 ; BDOS ERROR TABLE. - 112 ; - 0009r99s00 113 BADSCTR:.DW ERROR1 ; BAD SECTOR ON READ OR WRITE. - 000BrA5s00 114 BADSLCT:.DW ERROR2 ; BAD DISK SELECT. - 000DrABs00 115 RODISK: .DW ERROR3 ; DISK IS READ ONLY. - 000FrB1s00 116 ROFILE: .DW ERROR4 ; FILE IS READ ONLY. - 117 ; - 118 ; ENTRY INTO BDOS. (DE) OR (E) ARE THE PARAMETERS PASSED. THE - 119 ; FUNCTION NUMBER DESIRED IS IN REGISTER (C). - 120 ; E contains drive number if passing this - 0011 EB 121 FBASE1: EX DE,HL ; SAVE THE (DE) PARAMETERS. - 0012 22r43s03 122 LD (PARAMS),HL - 0015 EB 123 EX DE,HL - 0016 7B 124 LD A,E ; AND SAVE REGISTER (E) IN PARTICULAR. - 0017 32rD6s0D 125 LD (EPARAM),A - 001A 21 00 00 126 LD HL,#0 - 001D 22r45s03 127 LD (STATUS),HL ; CLEAR RETURN STATUS. - 0020 39 128 ADD HL,SP - 0021 22r0Fs03 129 LD (USRSTACK),HL ; SAVE USERS STACK POINTER. - 0024 31r41s03 130 LD SP,#STKAREA ; AND SET OUR OWN. - 0027 AF 131 XOR A ; CLEAR AUTO SELECT STORAGE SPACE. - 0028 32rE0s0D 132 LD (AUTOFLAG),A - 002B 32rDEs0D 133 LD (AUTO),A - 002E 21r74s0D 134 LD HL,#GOBACK ; SET RETURN ADDRESS. - 0031 E5 135 PUSH HL - 0032 79 136 LD A,C ; GET FUNCTION NUMBER. - 0033 FE 29 137 CP #NFUNCTS ; VALID FUNCTION NUMBER? - 0035 D0 138 RET NC - 0036 4B 139 LD C,E ; KEEP SINGLE REGISTER FUNCTION HERE. - 0037 21r47s00 140 LD HL,#FUNCTNS ; NOW LOOK THRU THE FUNCTION TABLE. - 003A 5F 141 LD E,A - 003B 16 00 142 LD D,#0 ; (DE)=FUNCTION NUMBER. - 003D 19 143 ADD HL,DE - 003E 19 144 ADD HL,DE ; (HL)=(START OF TABLE)+2*(FUNCTION NUMBER). - 003F 5E 145 LD E,(HL) - 0040 23 146 INC HL - 0041 56 147 LD D,(HL) ; NOW (DE)=ADDRESS FOR THIS FUNCTION. - 0042 2Ar43s03 148 LD HL,(PARAMS) ; RETRIEVE PARAMETERS. - 0045 EB 149 EX DE,HL ; NOW (DE) HAS THE ORIGINAL PARAMETERS. - 0046 E9 150 JP (HL) ; EXECUTE DESIRED FUNCTION. - 151 ; - 152 ; BDOS FUNCTION JUMP TABLE. - 153 ; - 0029 154 NFUNCTS = 41 ; NUMBER OF FUNCTIONS IN FOLLOWIN TABLE. - 155 ; - 0047 03 E6rC8s02r90s01 156 FUNCTNS:.DW WBOOT,GETCON,OUTCON,GETRDR,PUNCH,LIST,DIRCIO,GETIOB - rCEs02 12 E6 0F E6 - rD4s02rEDs02 - 0057rF3s02rF8s02rE1s01 157 .DW SETIOB,PRTSTR,R.DBUFF,GETCSTS,GETVER,RSTDSK,SETDSK,OPENFIL - rFEs02r7Es0Cr83s0C - r45s0Cr9Cs0C - 0067rA5s0CrABs0CrC8s0C 158 .DW CLOSEFIL,GETFST,GETNXT,DELFILE,READSEQ,WRTSEQ,FCREATE - rD7s0CrE0s0CrE6s0C - rECs0C - 0075rF5s0CrFEs0Cr04s0D 159 .DW RENFILE,GETLOG,GETCRNT,PUTDMA,GETALOC,WRTPRTD,GETROV,SETATTR - r0As0Dr11s0Dr2Cs05 - r17s0Dr1Ds0D - 0085r26s0Dr2Ds0Dr41s0D 160 .DW GETPARM,GETUSER,RDRANDOM,WTRANDOM,FILESIZE,SETRAN,LOGOFF,RTN - r47s0Dr4Ds0Dr0Es0C - r53s0Dr04s03 - 0095r04s03r9Bs0D 161 .DW RTN,WTSPECL - 162 ; - 163 ; BDOS ERROR MESSAGE SECTION. - 164 ; - 0099 21rCAs00 165 ERROR1: LD HL,#BADSEC ; BAD SECTOR MESSAGE. - 009C CDrE5s00 166 CALL PRTERR ; PRINT IT AND GET A 1 CHAR RESPONCE. - 009F FE 03 167 CP #CNTRLC ; RE-BOOT R.EQUEST (CONTROL-C)? - 00A1 CA 00 00 168 JP Z,0 ; YES. - 00A4 C9 169 RET ; NO, RETURN TO RETRY I/O FUNCTION. - 170 ; - 00A5 21rD5s00 171 ERROR2: LD HL,#BADSEL ; BAD DRIVE SELECTED. - 00A8 C3rB4s00 172 JP ERROR5 - 173 ; - 00AB 21rE1s00 174 ERROR3: LD HL,#DISKRO ; DISK IS READ ONLY. - 00AE C3rB4s00 175 JP ERROR5 - 176 ; - 00B1 21rDCs00 177 ERROR4: LD HL,#FILERO ; FILE IS READ ONLY. - 178 ; - 00B4 CDrE5s00 179 ERROR5: CALL PRTERR - 00B7 C3 00 00 180 JP 0 ; ALWAYS REBOOT ON THESE ERRORS. - 181 ; - 00BA 42 44 4F 53 20 45 182 BDOSERR: .ascii "BDOS ERR ON " - 52 52 20 4F 4E 20 - 00C6 20 3A 20 24 183 BDOSDRV: .ascii " : $" - 00CA 42 41 44 20 53 45 184 BADSEC: .ascii "BAD SECTOR$" - 43 54 4F 52 24 - 00D5 53 45 4C 45 43 54 185 BADSEL: .ascii "SELECT$" - 24 - 00DC 46 49 4C 45 20 186 FILERO: .ascii "FILE " - 00E1 52 2F 4F 24 187 DISKRO: .ascii "R/O$" - 188 ; - 189 ; PRINT BDOS ERROR MESSAGE. - 190 ; - 00E5 E5 191 PRTERR: PUSH HL ; SAVE SECOND MESSAGE POINTER. - 00E6 CDrC9s01 192 CALL OUTCRLF ; SEND (CR)(LF). - 00E9 3Ar42s03 193 LD A,(ACTIVE) ; GET ACTIVE DRIVE. - 00EC C6 41 194 ADD A,#ASCIIA ; MAKE ASCII. - 00EE 32rC6s00 195 LD (BDOSDRV),A ; AND PUT IN MESSAGE. - 00F1 01rBAs00 196 LD BC,#BDOSERR ; AND PRINT IT. - 00F4 CDrD3s01 197 CALL PRTMESG - 00F7 C1 198 POP BC ; PRINT SECOND MESSAGE LINE NOW. - 00F8 CDrD3s01 199 CALL PRTMESG - 200 ; - 201 ; GET AN INPUT CHARACTER. WE WILL CHECK OUR 1 CHARACTER - 202 ; BUFFER FIRST. THIS MAY BE SET BY THE CONSOLE STATUS ROUTINE. - 203 ; - 00FB 21r0Es03 204 GETCHAR:LD HL,#CHARBUF ; CHECK CHARACTER BUFFER. - 00FE 7E 205 LD A,(HL) ; ANYTHING PRESENT ALREADY? - 00FF 36 00 206 LD (HL),#0 ; ...EITHER CASE CLEAR IT. - 0101 B7 207 OR A - 0102 C0 208 RET NZ ; YES, USE IT. - 0103 C3 09 E6 209 JP CONIN ; NOPE, GO GET A CHARACTER RESPONCE. - 210 ; - 211 ; INPUT AND ECHO A CHARACTER. - 212 ; - 0106 CDrFBs00 213 GETECHO:CALL GETCHAR ; INPUT A CHARACTER. - 0109 CDr14s01 214 CALL CHKCHAR ; CARRIAGE CONTROL? - 010C D8 215 RET C ; NO, A REGULAR CONTROL CHAR SO DON'T ECHO. - 010D F5 216 PUSH AF ; OK, SAVE CHARACTER NOW. - 010E 4F 217 LD C,A - 010F CDr90s01 218 CALL OUTCON ; AND ECHO IT. - 0112 F1 219 POP AF ; GET CHARACTER AND RETURN. - 0113 C9 220 RET - 221 ; - 222 ; CHECK CHARACTER IN (A). SET THE ZERO FLAG ON A CARRIAGE - 223 ; CONTROL CHARACTER AND THE CARRY FLAG ON ANY OTHER CONTROL - 224 ; CHARACTER. - 225 ; - 0114 FE 0D 226 CHKCHAR:CP #CR ; CHECK FOR CARRIAGE RETURN, LINE FEED, BACKSPACE, - 0116 C8 227 RET Z ; OR A TAB. - 0117 FE 0A 228 CP #LF - 0119 C8 229 RET Z - 011A FE 09 230 CP #TAB - 011C C8 231 RET Z - 011D FE 08 232 CP #BS - 011F C8 233 RET Z - 0120 FE 20 234 CP #SPACE ; OTHER CONTROL CHAR? SET CARRY FLAG. - 0122 C9 235 RET - 236 ; - 237 ; CHECK THE CONSOLE DURING OUTPUT. HALT ON A CONTROL-S, THEN - 238 ; REBOOT ON A CONTROL-C. IF ANYTHING ELSE IS READY, CLEAR THE - 239 ; ZERO FLAG AND RETURN (THE CALLING ROUTINE MAY WANT TO DO - 240 ; SOMETHING). - 241 ; - 0123 242 CKCONSOL: - 0123 3Ar0Es03 243 LD A,(CHARBUF) ; CHECK BUFFER. - 0126 B7 244 OR A ; IF ANYTHING, JUST RETURN WITHOUT CHECKING. - 0127 C2r45s01 245 JP NZ,CKCON2 - 012A CD 06 E6 246 CALL CONST ; NOTHING IN BUFFER. CHECK CONSOLE. - 012D E6 01 247 AND #0x01 ; LOOK AT BIT 0. - 012F C8 248 RET Z ; RETURN IF NOTHING. - 0130 CD 09 E6 249 CALL CONIN ; OK, GET IT. - 0133 FE 13 250 CP #CNTRLS ; IF NOT CONTROL-S, RETURN WITH ZERO CLEARED. - 0135 C2r42s01 251 JP NZ,CKCON1 - 0138 CD 09 E6 252 CALL CONIN ; HALT PROCESSING UNTIL ANOTHER CHAR - 013B FE 03 253 CP #CNTRLC ; IS TYPED. CONTROL-C? - 013D CA 00 00 254 JP Z,0 ; YES, REBOOT NOW. - 0140 AF 255 XOR A ; NO, JUST PRETEND NOTHING WAS EVER READY. - 0141 C9 256 RET - 0142 32r0Es03 257 CKCON1: LD (CHARBUF),A ; SAVE CHARACTER IN BUFFER FOR LATER PROCESSING. - 0145 3E 01 258 CKCON2: LD A,#1 ; SET (A) TO NON ZERO TO MEAN SOMETHING IS READY. - 0147 C9 259 RET - 260 ; - 261 ; OUTPUT (C) TO THE SCREEN. IF THE PRINTER FLIP-FLOP FLAG - 262 ; IS SET, WE WILL SEND CHARACTER TO PRINTER ALSO. THE CONSOLE - 263 ; WILL BE CHECKED IN THE PROCESS. - 264 ; - 0148 3Ar0As03 265 OUTCHAR:LD A,(OUTFLAG) ; CHECK OUTPUT FLAG. - 014B B7 266 OR A ; ANYTHING AND WE WON'T GENERATE OUTPUT. - 014C C2r62s01 267 JP NZ,OUTCHR1 - 014F C5 268 PUSH BC - 0150 CDr23s01 269 CALL CKCONSOL ; CHECK CONSOLE (WE DON'T CARE WHATS THERE). - 0153 C1 270 POP BC - 0154 C5 271 PUSH BC - 0155 CD 0C E6 272 CALL CONOUT ; OUTPUT (C) TO THE SCREEN. - 0158 C1 273 POP BC - 0159 C5 274 PUSH BC - 015A 3Ar0Ds03 275 LD A,(PRTFLAG) ; CHECK PRINTER FLIP-FLOP FLAG. - 015D B7 276 OR A - 015E C4 0F E6 277 CALL NZ,LIST ; PRINT IT ALSO IF NON-ZERO. - 0161 C1 278 POP BC - 0162 79 279 OUTCHR1:LD A,C ; UPDATE CURSORS POSITION. - 0163 21r0Cs03 280 LD HL,#CURPOS - 0166 FE 7F 281 CP #DEL ; RUBOUTS DON'T DO ANYTHING HERE. - 0168 C8 282 RET Z - 0169 34 283 INC (HL) ; BUMP LINE POINTER. - 016A FE 20 284 CP #SPACE ; AND RETURN IF A NORMAL CHARACTER. - 016C D0 285 RET NC - 016D 35 286 DEC (HL) ; RESTORE AND CHECK FOR THE START OF THE LINE. - 016E 7E 287 LD A,(HL) - 016F B7 288 OR A - 0170 C8 289 RET Z ; INGNORE CONTROL CHARACTERS AT THE START OF THE LINE. - 0171 79 290 LD A,C - 0172 FE 08 291 CP #BS ; IS IT A BACKSPACE? - 0174 C2r79s01 292 JP NZ,OUTCHR2 - 0177 35 293 DEC (HL) ; YES, BACKUP POINTER. - 0178 C9 294 RET - 0179 FE 0A 295 OUTCHR2:CP #LF ; IS IT A LINE FEED? - 017B C0 296 RET NZ ; IGNORE ANYTHING ELSE. - 017C 36 00 297 LD (HL),#0 ; RESET POINTER TO START OF LINE. - 017E C9 298 RET - 299 ; - 300 ; OUTPUT (A) TO THE SCREEN. IF IT IS A CONTROL CHARACTER - 301 ; (OTHER THAN CARRIAGE CONTROL), USE ^X FORMAT. - 302 ; - 017F 79 303 SHOWIT: LD A,C - 0180 CDr14s01 304 CALL CHKCHAR ; CHECK CHARACTER. - 0183 D2r90s01 305 JP NC,OUTCON ; NOT A CONTROL, USE NORMAL OUTPUT. - 0186 F5 306 PUSH AF - 0187 0E 5E 307 LD C,#UP ; FOR A CONTROL CHARACTER, PRECEED IT WITH '^'. - 0189 CDr48s01 308 CALL OUTCHAR - 018C F1 309 POP AF - 018D F6 40 310 OR #AT ; AND THEN USE THE LETTER .EQUIVELANT. - 018F 4F 311 LD C,A - 312 ; - 313 ; FUNCTION TO OUTPUT (C) TO THE CONSOLE DEVICE AND EXPAND TABS - 314 ; IF NECESSARY. - 315 ; - 0190 79 316 OUTCON: LD A,C - 0191 FE 09 317 CP #TAB ; IS IT A TAB? - 0193 C2r48s01 318 JP NZ,OUTCHAR ; USE REGULAR OUTPUT. - 0196 0E 20 319 OUTCON1:LD C,#SPACE ; YES IT IS, USE SPACES INSTEAD. - 0198 CDr48s01 320 CALL OUTCHAR - 019B 3Ar0Cs03 321 LD A,(CURPOS) ; GO UNTIL THE CURSOR IS AT A MULTIPLE OF 8 - 322 - 019E E6 07 323 AND #7 ; POSITION. - 01A0 C2r96s01 324 JP NZ,OUTCON1 - 01A3 C9 325 RET - 326 ; - 327 ; ECHO A BACKSPACE CHARACTER. ERASE THE PREVOIUS CHARACTER - 328 ; ON THE SCREEN. - 329 ; - 01A4 CDrACs01 330 BACKUP: CALL BACKUP1 ; BACKUP THE SCREEN 1 PLACE. - 01A7 0E 20 331 LD C,#SPACE ; THEN BLANK THAT CHARACTER. - 01A9 CD 0C E6 332 CALL CONOUT - 01AC 0E 08 333 BACKUP1:LD C,#BS ; THEN BACK SPACE ONCE MORE. - 01AE C3 0C E6 334 JP CONOUT - 335 ; - 336 ; SIGNAL A DELETED LINE. PRINT A '#' AT THE END AND START - 337 ; OVER. - 338 ; - 01B1 0E 23 339 NEWLINE:LD C,#POUND - 01B3 CDr48s01 340 CALL OUTCHAR ; PRINT THIS. - 01B6 CDrC9s01 341 CALL OUTCRLF ; START NEW LINE. - 01B9 3Ar0Cs03 342 NEWLN1: LD A,(CURPOS) ; MOVE THE CURSOR TO THE STARTING POSITION. - 01BC 21r0Bs03 343 LD HL,#STARTING - 01BF BE 344 CP (HL) - 01C0 D0 345 RET NC ; THERE YET? - 01C1 0E 20 346 LD C,#SPACE - 01C3 CDr48s01 347 CALL OUTCHAR ; NOPE, KEEP GOING. - 01C6 C3rB9s01 348 JP NEWLN1 - 349 ; - 350 ; OUTPUT A (CR) (LF) TO THE CONSOLE DEVICE (SCREEN). - 351 ; - 01C9 0E 0D 352 OUTCRLF:LD C,#CR - 01CB CDr48s01 353 CALL OUTCHAR - 01CE 0E 0A 354 LD C,#LF - 01D0 C3r48s01 355 JP OUTCHAR - 356 ; - 357 ; PRINT MESSAGE POINTED TO BY (BC). IT WILL END WITH A '$'. - 358 ; - 01D3 0A 359 PRTMESG:LD A,(BC) ; CHECK FOR TERMINATING CHARACTER. - 01D4 FE 24 360 CP #DOLLAR - 01D6 C8 361 RET Z - 01D7 03 362 INC BC - 01D8 C5 363 PUSH BC ; OTHERWISE, BUMP POINTER AND PRINT IT. - 01D9 4F 364 LD C,A - 01DA CDr90s01 365 CALL OUTCON - 01DD C1 366 POP BC - 01DE C3rD3s01 367 JP PRTMESG - 368 ; - 369 ; FUNCTION TO EXECUTE A BUFFERED READ. - 370 ; - 01E1 3Ar0Cs03 371 R.DBUFF: LD A,(CURPOS) ; USE PRESENT LOCATION AS STARTING ONE. - 01E4 32r0Bs03 372 LD (STARTING),A - 01E7 2Ar43s03 373 LD HL,(PARAMS) ; GET THE MAXIMUM BUFFER SPACE. - 01EA 4E 374 LD C,(HL) - 01EB 23 375 INC HL ; POINT TO FIRST AVAILABLE SPACE. - 01EC E5 376 PUSH HL ; AND SAVE. - 01ED 06 00 377 LD B,#0 ; KEEP A CHARACTER COUNT. - 01EF C5 378 R.DBUF1: PUSH BC - 01F0 E5 379 PUSH HL - 01F1 CDrFBs00 380 R.DBUF2: CALL GETCHAR ; GET THE NEXT INPUT CHARACTER. - 01F4 E6 7F 381 AND #0x7F ; STRIP BIT 7. - 01F6 E1 382 POP HL ; RESET REGISTERS. - 01F7 C1 383 POP BC - 01F8 FE 0D 384 CP #CR ; EN OF THE LINE? - 01FA CArC1s02 385 JP Z,R.DBUF17 - 01FD FE 0A 386 CP #LF - 01FF CArC1s02 387 JP Z,R.DBUF17 - 0202 FE 08 388 CP #BS ; HOW ABOUT A BACKSPACE? - 0204 C2r16s02 389 JP NZ,R.DBUF3 - 0207 78 390 LD A,B ; YES, BUT IGNORE AT THE BEGINNING OF THE LINE. - 0208 B7 391 OR A - 0209 CArEFs01 392 JP Z,R.DBUF1 - 020C 05 393 DEC B ; OK, UPDATE COUNTER. - 020D 3Ar0Cs03 394 LD A,(CURPOS) ; IF WE BACKSPACE TO THE START OF THE LINE, - 0210 32r0As03 395 LD (OUTFLAG),A ; TREAT AS A CANCEL (CONTROL-X). - 0213 C3r70s02 396 JP R.DBUF10 - 0216 FE 7F 397 R.DBUF3: CP #DEL ; USER TYPED A RUBOUT? - 0218 C2r26s02 398 JP NZ,R.DBUF4 - 021B 78 399 LD A,B ; IGNORE AT THE START OF THE LINE. - 021C B7 400 OR A - 021D CArEFs01 401 JP Z,R.DBUF1 - 0220 7E 402 LD A,(HL) ; OK, ECHO THE PREVOIUS CHARACTER. - 0221 05 403 DEC B ; AND RESET POINTERS (COUNTERS). - 0222 2B 404 DEC HL - 0223 C3rA9s02 405 JP R.DBUF15 - 0226 FE 05 406 R.DBUF4: CP #CNTRLE ; PHYSICAL END OF LINE? - 0228 C2r37s02 407 JP NZ,R.DBUF5 - 022B C5 408 PUSH BC ; YES, DO IT. - 022C E5 409 PUSH HL - 022D CDrC9s01 410 CALL OUTCRLF - 0230 AF 411 XOR A ; AND UPDATE STARTING POSITION. - 0231 32r0Bs03 412 LD (STARTING),A - 0234 C3rF1s01 413 JP R.DBUF2 - 0237 FE 10 414 R.DBUF5: CP #CNTRLP ; CONTROL-P? - 0239 C2r48s02 415 JP NZ,R.DBUF6 - 023C E5 416 PUSH HL ; YES, FLIP THE PRINT FLAG FILP-FLOP BYTE. - 023D 21r0Ds03 417 LD HL,#PRTFLAG - 0240 3E 01 418 LD A,#1 ; PRTFLAG=1-PRTFLAG - 0242 96 419 SUB (HL) - 0243 77 420 LD (HL),A - 0244 E1 421 POP HL - 0245 C3rEFs01 422 JP R.DBUF1 - 0248 FE 18 423 R.DBUF6: CP #CNTRLX ; CONTROL-X (CANCEL)? - 024A C2r5Fs02 424 JP NZ,R.DBUF8 - 024D E1 425 POP HL - 024E 3Ar0Bs03 426 R.DBUF7: LD A,(STARTING) ; YES, BACKUP THE CURSOR TO HERE. - 0251 21r0Cs03 427 LD HL,#CURPOS - 0254 BE 428 CP (HL) - 0255 D2rE1s01 429 JP NC,R.DBUFF ; DONE YET? - 0258 35 430 DEC (HL) ; NO, DECREMENT POINTER AND OUTPUT BACK UP ONE SPACE. - 0259 CDrA4s01 431 CALL BACKUP - 025C C3r4Es02 432 JP R.DBUF7 - 025F FE 15 433 R.DBUF8: CP #CNTRLU ; CNTROL-U (CANCEL LINE)? - 0261 C2r6Bs02 434 JP NZ,R.DBUF9 - 0264 CDrB1s01 435 CALL NEWLINE ; START A NEW LINE. - 0267 E1 436 POP HL - 0268 C3rE1s01 437 JP R.DBUFF - 026B FE 12 438 R.DBUF9: CP #CNTRLR ; CONTROL-R? - 026D C2rA6s02 439 JP NZ,R.DBUF14 - 0270 C5 440 R.DBUF10:PUSH BC ; YES, START A NEW LINE AND RETYPE THE OLD ONE. - 0271 CDrB1s01 441 CALL NEWLINE - 0274 C1 442 POP BC - 0275 E1 443 POP HL - 0276 E5 444 PUSH HL - 0277 C5 445 PUSH BC - 0278 78 446 R.DBUF11:LD A,B ; DONE WHOLE LINE YET? - 0279 B7 447 OR A - 027A CAr8As02 448 JP Z,R.DBUF12 - 027D 23 449 INC HL ; NOPE, GET NEXT CHARACTER. - 027E 4E 450 LD C,(HL) - 027F 05 451 DEC B ; COUNT IT. - 0280 C5 452 PUSH BC - 0281 E5 453 PUSH HL - 0282 CDr7Fs01 454 CALL SHOWIT ; AND DISPLAY IT. - 0285 E1 455 POP HL - 0286 C1 456 POP BC - 0287 C3r78s02 457 JP R.DBUF11 - 028A E5 458 R.DBUF12:PUSH HL ; DONE WITH LINE. IF WE WERE DISPLAYING - 028B 3Ar0As03 459 LD A,(OUTFLAG) ; THEN UPDATE CURSOR POSITION. - 028E B7 460 OR A - 028F CArF1s01 461 JP Z,R.DBUF2 - 0292 21r0Cs03 462 LD HL,#CURPOS ; BECAUSE THIS LINE IS SHORTER, WE MUST - 0295 96 463 SUB (HL) ; BACK UP THE CURSOR (NOT THE SCREEN HOWEVER) - 0296 32r0As03 464 LD (OUTFLAG),A ; SOME NUMBER OF POSITIONS. - 0299 CDrA4s01 465 R.DBUF13:CALL BACKUP ; NOTE THAT AS LONG AS (OUTFLAG) IS NON - 029C 21r0As03 466 LD HL,#OUTFLAG ; ZERO, THE SCREEN WILL NOT BE CHANGED. - 029F 35 467 DEC (HL) - 02A0 C2r99s02 468 JP NZ,R.DBUF13 - 02A3 C3rF1s01 469 JP R.DBUF2 ; NOW JUST GET THE NEXT CHARACTER. - 470 ; - 471 ; JUST A NORMAL CHARACTER, PUT THIS IN OUR BUFFER AND ECHO. - 472 ; - 02A6 23 473 R.DBUF14:INC HL - 02A7 77 474 LD (HL),A ; STORE CHARACTER. - 02A8 04 475 INC B ; AND COUNT IT. - 02A9 C5 476 R.DBUF15:PUSH BC - 02AA E5 477 PUSH HL - 02AB 4F 478 LD C,A ; ECHO IT NOW. - 02AC CDr7Fs01 479 CALL SHOWIT - 02AF E1 480 POP HL - 02B0 C1 481 POP BC - 02B1 7E 482 LD A,(HL) ; WAS IT AN ABORT R.EQUEST? - 02B2 FE 03 483 CP #CNTRLC ; CONTROL-C ABORT? - 02B4 78 484 LD A,B - 02B5 C2rBDs02 485 JP NZ,R.DBUF16 - 02B8 FE 01 486 CP #1 ; ONLY IF AT START OF LINE. - 02BA CA 00 00 487 JP Z,0 - 02BD B9 488 R.DBUF16:CP C ; NOPE, HAVE WE FILLED THE BUFFER? - 02BE DArEFs01 489 JP C,R.DBUF1 - 02C1 E1 490 R.DBUF17:POP HL ; YES END THE LINE AND RETURN. - 02C2 70 491 LD (HL),B - 02C3 0E 0D 492 LD C,#CR - 02C5 C3r48s01 493 JP OUTCHAR ; OUTPUT (CR) AND RETURN. - 494 ; - 495 ; FUNCTION TO GET A CHARACTER FROM THE CONSOLE DEVICE. - 496 ; - 02C8 CDr06s01 497 GETCON: CALL GETECHO ; GET AND ECHO. - 02CB C3r01s03 498 JP SETSTAT ; SAVE STATUS AND RETURN. - 499 ; - 500 ; FUNCTION TO GET A CHARACTER FROM THE TAPE READER DEVICE. - 501 ; - 02CE CD 15 E6 502 GETRDR: CALL READER ; GET A CHARACTER FROM READER, SET STATUS AND RETURN. - 02D1 C3r01s03 503 JP SETSTAT - 504 ; - 505 ; FUNCTION TO PERFORM DIRECT CONSOLE I/O. IF (C) CONTAINS (FF) - 506 ; THEN THIS IS AN INPUT R.EQUEST. IF (C) CONTAINS (FE) THEN - 507 ; THIS IS A STATUS R.EQUEST. OTHERWISE WE ARE TO OUTPUT (C). - 508 ; - 02D4 79 509 DIRCIO: LD A,C ; TEST FOR (FF). - 02D5 3C 510 INC A - 02D6 CArE0s02 511 JP Z,DIRC1 - 02D9 3C 512 INC A ; TEST FOR (FE). - 02DA CA 06 E6 513 JP Z,CONST - 02DD C3 0C E6 514 JP CONOUT ; JUST OUTPUT (C). - 02E0 CD 06 E6 515 DIRC1: CALL CONST ; THIS IS AN INPUT R.EQUEST. - 02E3 B7 516 OR A - 02E4 CAr91s0D 517 JP Z,GOBACK1 ; NOT READY? JUST RETURN (DIRECTLY). - 02E7 CD 09 E6 518 CALL CONIN ; YES, GET CHARACTER. - 02EA C3r01s03 519 JP SETSTAT ; SET STATUS AND RETURN. - 520 ; - 521 ; FUNCTION TO RETURN THE I/O BYTE. - 522 ; - 02ED 3A 03 00 523 GETIOB: LD A,(IOBYTE) - 02F0 C3r01s03 524 JP SETSTAT - 525 ; - 526 ; FUNCTION TO SET THE I/O BYTE. - 527 ; - 02F3 21 03 00 528 SETIOB: LD HL,#IOBYTE - 02F6 71 529 LD (HL),C - 02F7 C9 530 RET - 531 ; - 532 ; FUNCTION TO PRINT THE CHARACTER STRING POINTED TO BY (DE) - 533 ; ON THE CONSOLE DEVICE. THE STRING ENDS WITH A '$'. - 534 ; - 02F8 EB 535 PRTSTR: EX DE,HL - 02F9 4D 536 LD C,L - 02FA 44 537 LD B,H ; NOW (BC) POINTS TO IT. - 02FB C3rD3s01 538 JP PRTMESG - 539 ; - 540 ; FUNCTION TO INTERIGATE THE CONSOLE DEVICE. - 541 ; - 02FE CDr23s01 542 GETCSTS:CALL CKCONSOL - 543 ; - 544 ; GET HERE TO SET THE STATUS AND RETURN TO THE CLEANUP - 545 ; SECTION. THEN BACK TO THE USER. - 546 ; - 0301 32r45s03 547 SETSTAT:LD (STATUS),A - 0304 C9 548 RTN: RET - 549 ; - 550 ; SET THE STATUS TO 1 (READ OR WRITE ERROR CODE). - 551 ; - 0305 3E 01 552 IOERR1: LD A,#1 - 0307 C3r01s03 553 JP SETSTAT - 554 ; - 030A 00 555 OUTFLAG:.DB 0 ; OUTPUT FLAG (NON ZERO MEANS NO OUTPUT). - 030B 556 STARTING: - 030B 02 557 .DB 2 ; STARTING POSITION FOR CURSOR. - 030C 00 558 CURPOS: .DB 0 ; CURSOR POSITION (0=START OF LINE). - 030D 00 559 PRTFLAG:.DB 0 ; PRINTER FLAG (CONTROL-P TOGGLE). LIST IF NON ZERO. - 030E 00 560 CHARBUF:.DB 0 ; SINGLE INPUT CHARACTER BUFFER. - 561 ; - 562 ; STACK AREA FOR BDOS CALLS. - 563 ; - 030F 564 USRSTACK: - 030F 00 00 565 .DW 0 ; SAVE USERS STACK POINTER HERE. - 566 ; - 0311 00 00 00 00 00 00 567 .DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - 00 00 00 00 00 00 - 00 00 00 00 00 00 - 00 00 00 00 00 00 - 0329 00 00 00 00 00 00 568 .DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - 00 00 00 00 00 00 - 00 00 00 00 00 00 - 00 00 00 00 00 00 - 0341 569 STKAREA: ; END OF STACK AREA. - 570 ; - 0341 00 571 USERNO: .DB 0 ; CURRENT USER NUMBER. - 0342 00 572 ACTIVE: .DB 0 ; CURRENTLY ACTIVE DRIVE. - 0343 00 00 573 PARAMS: .DW 0 ; SAVE (DE) PARAMETERS HERE ON ENTRY. - 0345 00 00 574 STATUS: .DW 0 ; STATUS RETURNED FROM BDOS FUNCTION. - 575 ; - 576 ; SELECT ERROR OCCURED, JUMP TO ERROR ROUTINE. - 577 ; - 0347 21r0Bs00 578 SLCTERR:LD HL,#BADSLCT - 579 ; - 580 ; JUMP TO (HL) INDIRECTLY. - 581 ; - 034A 5E 582 JUMPHL: LD E,(HL) - 034B 23 583 INC HL - 034C 56 584 LD D,(HL) ; NOW (DE) CONTAIN THE DESIRED ADDRESS. - 034D EB 585 EX DE,HL - 034E E9 586 JP (HL) - 587 ; - 588 ; BLOCK MOVE. (DE) TO (HL), (C) BYTES TOTAL. - 589 ; - 034F 0C 590 DE2HL: INC C ; IS COUNT DOWN TO ZERO? - 0350 0D 591 DE2HL1: DEC C - 0351 C8 592 RET Z ; YES, WE ARE DONE. - 0352 1A 593 LD A,(DE) ; NO, MOVE ONE MORE BYTE. - 0353 77 594 LD (HL),A - 0354 13 595 INC DE - 0355 23 596 INC HL - 0356 C3r50s03 597 JP DE2HL1 ; AND REPEAT. - 598 ; - 599 ; SELECT THE DESIRED DRIVE. - 600 ; - 0359 3Ar42s03 601 SELECT: LD A,(ACTIVE) ; GET ACTIVE DISK. - 035C 4F 602 LD C,A - 035D CD 1B E6 603 CALL SELDSK ; SELECT IT. - 0360 7C 604 LD A,H ; VALID DRIVE? - 0361 B5 605 OR L ; VALID DRIVE? - 0362 C8 606 RET Z ; RETURN IF NOT. - 607 ; - 608 ; HERE, THE BIOS RETURNED THE ADDRESS OF THE PARAMETER BLOCK - 609 ; IN (HL). WE WILL EXTRACT THE NECESSARY POINTERS AND SAVE THEM. - 610 ; - 0363 5E 611 LD E,(HL) ; YES, GET ADDRESS OF TRANSLATION TABLE INTO (DE). - 0364 23 612 INC HL - 0365 56 613 LD D,(HL) - 0366 23 614 INC HL - 0367 22rB3s0D 615 LD (SCRATCH1),HL ; SAVE POINTERS TO SCRATCH AREAS. - 036A 23 616 INC HL - 036B 23 617 INC HL - 036C 22rB5s0D 618 LD (SCRATCH2),HL ; DITTO. - 036F 23 619 INC HL - 0370 23 620 INC HL - 0371 22rB7s0D 621 LD (SCRATCH3),HL ; DITTO. - 0374 23 622 INC HL - 0375 23 623 INC HL - 0376 EB 624 EX DE,HL ; NOW SAVE THE TRANSLATION TABLE ADDRESS. - 0377 22rD0s0D 625 LD (XLATE),HL - 037A 21rB9s0D 626 LD HL,#DIRBUF ; PUT THE NEXT 8 BYTES HERE. - 037D 0E 08 627 LD C,#8 ; THEY CONSIST OF THE DIRECTORY BUFFER - 037F CDr4Fs03 628 CALL DE2HL ; POINTER, PARAMETER BLOCK POINTER, - 0382 2ArBBs0D 629 LD HL,(DISKPB) ; CHECK AND ALLOCATION VECTORS. - 0385 EB 630 EX DE,HL - 0386 21rC1s0D 631 LD HL,#SECTORS ; MOVE PARAMETER BLOCK INTO OUR RAM. - 0389 0E 0F 632 LD C,#15 ; IT IS 15 BYTES LONG. - 038B CDr4Fs03 633 CALL DE2HL - 038E 2ArC6s0D 634 LD HL,(DSKSIZE) ; CHECK DISK SIZE. - 0391 7C 635 LD A,H ; MORE THAN 256 BLOCKS ON THIS? - 0392 21rDDs0D 636 LD HL,#BIGDISK - 0395 36 FF 637 LD (HL),#0x0FF ; SET TO SAMLL. - 0397 B7 638 OR A - 0398 CAr9Ds03 639 JP Z,SELECT1 - 039B 36 00 640 LD (HL),#0 ; WRONG, SET TO LARGE. - 039D 3E FF 641 SELECT1:LD A,#0x0FF ; CLEAR THE ZERO FLAG. - 039F B7 642 OR A - 03A0 C9 643 RET - 644 ; - 645 ; ROUTINE TO HOME THE DISK TRACK HEAD AND CLEAR POINTERS. - 646 ; - 03A1 CD 18 E6 647 HOMEDRV:CALL HOME ; HOME THE HEAD. - 03A4 AF 648 XOR A - 03A5 2ArB5s0D 649 LD HL,(SCRATCH2) ; SET OUR TRACK POINTER ALSO. - 03A8 77 650 LD (HL),A - 03A9 23 651 INC HL - 03AA 77 652 LD (HL),A - 03AB 2ArB7s0D 653 LD HL,(SCRATCH3) ; AND OUR SECTOR POINTER. - 03AE 77 654 LD (HL),A - 03AF 23 655 INC HL - 03B0 77 656 LD (HL),A - 03B1 C9 657 RET - 658 ; - 659 ; DO THE ACTUAL DISK READ AND CHECK THE ERROR RETURN STATUS. - 660 ; - 03B2 CD 27 E6 661 DOREAD: CALL READ - 03B5 C3rBBs03 662 JP IORET - 663 ; - 664 ; DO THE ACTUAL DISK WRITE AND HANDLE ANY BIOS ERROR. - 665 ; - 03B8 CD 2A E6 666 DOWRITE:CALL WRITE - 03BB B7 667 IORET: OR A - 03BC C8 668 RET Z ; RETURN UNLESS AN ERROR OCCURED. - 03BD 21r09s00 669 LD HL,#BADSCTR ; BAD READ/WRITE ON THIS SECTOR. - 03C0 C3r4As03 670 JP JUMPHL - 671 ; - 672 ; ROUTINE TO SELECT THE TRACK AND SECTOR THAT THE DESIRED - 673 ; BLOCK NUMBER FALLS IN. - 674 ; - 03C3 2ArEAs0D 675 TRKSEC: LD HL,(FILEPOS) ; GET POSITION OF LAST ACCESSED FILE - 03C6 0E 02 676 LD C,#2 ; IN DIRECTORY AND COMPUTE SECTOR #. - 03C8 CDrEAs04 677 CALL SHIFTR ; SECTOR #=FILE-POSITION/4. - 03CB 22rE5s0D 678 LD (BLKNMBR),HL ; SAVE THIS AS THE BLOCK NUMBER OF INTEREST. - 03CE 22rECs0D 679 LD (CKSUMTBL),HL ; WHAT'S IT DOING HERE TOO? - 680 ; - 681 ; IF THE SECTOR NUMBER HAS ALREADY BEEN SET (BLKNMBR), ENTER - 682 ; AT THIS POINT. - 683 ; - 03D1 21rE5s0D 684 TRKSEC1:LD HL,#BLKNMBR - 03D4 4E 685 LD C,(HL) ; MOVE SECTOR NUMBER INTO (BC). - 03D5 23 686 INC HL - 03D6 46 687 LD B,(HL) - 03D7 2ArB7s0D 688 LD HL,(SCRATCH3) ; GET CURRENT SECTOR NUMBER AND - 03DA 5E 689 LD E,(HL) ; MOVE THIS INTO (DE). - 03DB 23 690 INC HL - 03DC 56 691 LD D,(HL) - 03DD 2ArB5s0D 692 LD HL,(SCRATCH2) ; GET CURRENT TRACK NUMBER. - 03E0 7E 693 LD A,(HL) ; AND THIS INTO (HL). - 03E1 23 694 INC HL - 03E2 66 695 LD H,(HL) - 03E3 6F 696 LD L,A - 03E4 79 697 TRKSEC2:LD A,C ; IS DESIRED SECTOR BEFORE CURRENT ONE? - 03E5 93 698 SUB E - 03E6 78 699 LD A,B - 03E7 9A 700 SBC A,D - 03E8 D2rFAs03 701 JP NC,TRKSEC3 - 03EB E5 702 PUSH HL ; YES, DECREMENT SECTORS BY ONE TRACK. - 03EC 2ArC1s0D 703 LD HL,(SECTORS) ; GET SECTORS PER TRACK. - 03EF 7B 704 LD A,E - 03F0 95 705 SUB L - 03F1 5F 706 LD E,A - 03F2 7A 707 LD A,D - 03F3 9C 708 SBC A,H - 03F4 57 709 LD D,A ; NOW WE HAVE BACKED UP ONE FULL TRACK. - 03F5 E1 710 POP HL - 03F6 2B 711 DEC HL ; ADJUST TRACK COUNTER. - 03F7 C3rE4s03 712 JP TRKSEC2 - 03FA E5 713 TRKSEC3:PUSH HL ; DESIRED SECTOR IS AFTER CURRENT ONE. - 03FB 2ArC1s0D 714 LD HL,(SECTORS) ; GET SECTORS PER TRACK. - 03FE 19 715 ADD HL,DE ; BUMP SECTOR POINTER TO NEXT TRACK. - 03FF DAr0Fs04 716 JP C,TRKSEC4 - 0402 79 717 LD A,C ; IS DESIRED SECTOR NOW BEFORE CURRENT ONE? - 0403 95 718 SUB L - 0404 78 719 LD A,B - 0405 9C 720 SBC A,H - 0406 DAr0Fs04 721 JP C,TRKSEC4 - 0409 EB 722 EX DE,HL ; NOT YES, INCREMENT TRACK COUNTER - 040A E1 723 POP HL ; AND CONTINUE UNTIL IT IS. - 040B 23 724 INC HL - 040C C3rFAs03 725 JP TRKSEC3 - 726 ; - 727 ; HERE WE HAVE DETERMINED THE TRACK NUMBER THAT CONTAINS THE - 728 ; DESIRED SECTOR. - 729 ; - 040F E1 730 TRKSEC4:POP HL ; GET TRACK NUMBER (HL). - 0410 C5 731 PUSH BC - 0411 D5 732 PUSH DE - 0412 E5 733 PUSH HL - 0413 EB 734 EX DE,HL - 0414 2ArCEs0D 735 LD HL,(OFFSET) ; ADJUST FOR FIRST TRACK OFFSET. - 0417 19 736 ADD HL,DE - 0418 44 737 LD B,H - 0419 4D 738 LD C,L - 041A CD 1E E6 739 CALL SETTRK ; SELECT THIS TRACK. - 041D D1 740 POP DE ; RESET CURRENT TRACK POINTER. - 041E 2ArB5s0D 741 LD HL,(SCRATCH2) - 0421 73 742 LD (HL),E - 0422 23 743 INC HL - 0423 72 744 LD (HL),D - 0424 D1 745 POP DE - 0425 2ArB7s0D 746 LD HL,(SCRATCH3) ; RESET THE FIRST SECTOR ON THIS TRACK. - 0428 73 747 LD (HL),E - 0429 23 748 INC HL - 042A 72 749 LD (HL),D - 042B C1 750 POP BC - 042C 79 751 LD A,C ; NOW SUBTRACT THE DESIRED ONE. - 042D 93 752 SUB E ; TO MAKE IT RELATIVE (1-# SECTORS/TRACK). - 042E 4F 753 LD C,A - 042F 78 754 LD A,B - 0430 9A 755 SBC A,D - 0431 47 756 LD B,A - 0432 2ArD0s0D 757 LD HL,(XLATE) ; TRANSLATE THIS SECTOR ACCORDING TO THIS TABLE. - 0435 EB 758 EX DE,HL - 0436 CD 30 E6 759 CALL SECTRN ; LET THE BIOS TRANSLATE IT. - 0439 4D 760 LD C,L - 043A 44 761 LD B,H - 043B C3 21 E6 762 JP SETSEC ; AND SELECT IT. - 763 ; - 764 ; COMPUTE BLOCK NUMBER FROM RECORD NUMBER (SAVNREC) AND - 765 ; EXTENT NUMBER (SAVEXT). - 766 ; - 043E 767 GETBLOCK: - 043E 21rC3s0D 768 LD HL,#BLKSHFT ; GET LOGICAL TO PHYSICAL CONVERSION. - 0441 4E 769 LD C,(HL) ; NOTE THAT THIS IS BASE 2 LOG OF RATIO. - 0442 3ArE3s0D 770 LD A,(SAVNREC) ; GET RECORD NUMBER. - 0445 B7 771 GETBLK1:OR A ; COMPUTE (A)=(A)/2^BLKSHFT. - 0446 1F 772 RRA - 0447 0D 773 DEC C - 0448 C2r45s04 774 JP NZ,GETBLK1 - 044B 47 775 LD B,A ; SAVE RESULT IN (B). - 044C 3E 08 776 LD A,#8 - 044E 96 777 SUB (HL) - 044F 4F 778 LD C,A ; COMPUTE (C)=8-BLKSHFT. - 0450 3ArE2s0D 779 LD A,(SAVEXT) - 0453 0D 780 GETBLK2:DEC C ; COMPUTE (A)=SAVEXT*2^(8-BLKSHFT). - 0454 CAr5Cs04 781 JP Z,GETBLK3 - 0457 B7 782 OR A - 0458 17 783 RLA - 0459 C3r53s04 784 JP GETBLK2 - 045C 80 785 GETBLK3:ADD A,B - 045D C9 786 RET - 787 ; - 788 ; ROUTINE TO EXTRACT THE (BC) BLOCK BYTE FROM THE FCB POINTED - 789 ; TO BY (PARAMS). IF THIS IS A BIG-DISK, THEN THESE ARE 16 BIT - 790 ; BLOCK NUMBERS, ELSE THEY ARE 8 BIT NUMBERS. - 791 ; NUMBER IS RETURNED IN (HL). - 792 ; - 045E 2Ar43s03 793 EXTBLK: LD HL,(PARAMS) ; GET FCB ADDRESS. - 0461 11 10 00 794 LD DE,#16 ; BLOCK NUMBERS START 16 BYTES INTO FCB. - 0464 19 795 ADD HL,DE - 0465 09 796 ADD HL,BC - 0466 3ArDDs0D 797 LD A,(BIGDISK) ; ARE WE USING A BIG-DISK? - 0469 B7 798 OR A - 046A CAr71s04 799 JP Z,EXTBLK1 - 046D 6E 800 LD L,(HL) ; NO, EXTRACT AN 8 BIT NUMBER FROM THE FCB. - 046E 26 00 801 LD H,#0 - 0470 C9 802 RET - 0471 09 803 EXTBLK1:ADD HL,BC ; YES, EXTRACT A 16 BIT NUMBER. - 0472 5E 804 LD E,(HL) - 0473 23 805 INC HL - 0474 56 806 LD D,(HL) - 0475 EB 807 EX DE,HL ; RETURN IN (HL). - 0476 C9 808 RET - 809 ; - 810 ; COMPUTE BLOCK NUMBER. - 811 ; - 0477 CDr3Es04 812 COMBLK: CALL GETBLOCK - 047A 4F 813 LD C,A - 047B 06 00 814 LD B,#0 - 047D CDr5Es04 815 CALL EXTBLK - 0480 22rE5s0D 816 LD (BLKNMBR),HL - 0483 C9 817 RET - 818 ; - 819 ; CHECK FOR A ZERO BLOCK NUMBER (UNUSED). - 820 ; - 0484 2ArE5s0D 821 CHKBLK: LD HL,(BLKNMBR) - 0487 7D 822 LD A,L ; IS IT ZERO? - 0488 B4 823 OR H - 0489 C9 824 RET - 825 ; - 826 ; ADJUST PHYSICAL BLOCK (BLKNMBR) AND CONVERT TO LOGICAL - 827 ; SECTOR (LOGSECT). THIS IS THE STARTING SECTOR OF THIS BLOCK. - 828 ; THE ACTUAL SECTOR OF INTEREST IS THEN ADDED TO THIS AND THE - 829 ; RESULTING SECTOR NUMBER IS STORED BACK IN (BLKNMBR). THIS - 830 ; WILL STILL HAVE TO BE ADJUSTED FOR THE TRACK NUMBER. - 831 ; - 048A 3ArC3s0D 832 LOGICAL:LD A,(BLKSHFT) ; GET LOG2(PHYSICAL/LOGICAL SECTORS). - 048D 2ArE5s0D 833 LD HL,(BLKNMBR) ; GET PHYSICAL SECTOR DESIRED. - 0490 29 834 LOGICL1:ADD HL,HL ; COMPUTE LOGICAL SECTOR NUMBER. - 0491 3D 835 DEC A ; NOTE LOGICAL SECTORS ARE 128 BYTES LONG. - 0492 C2r90s04 836 JP NZ,LOGICL1 - 0495 22rE7s0D 837 LD (LOGSECT),HL ; SAVE LOGICAL SECTOR. - 0498 3ArC4s0D 838 LD A,(BLKMASK) ; GET BLOCK MASK. - 049B 4F 839 LD C,A - 049C 3ArE3s0D 840 LD A,(SAVNREC) ; GET NEXT SECTOR TO ACCESS. - 049F A1 841 AND C ; EXTRACT THE RELATIVE POSITION WITHIN PHYSICAL BLOCK. - 04A0 B5 842 OR L ; AND ADD IT TOO LOGICAL SECTOR. - 04A1 6F 843 LD L,A - 04A2 22rE5s0D 844 LD (BLKNMBR),HL ; AND STORE. - 04A5 C9 845 RET - 846 ; - 847 ; SET (HL) TO POINT TO EXTENT BYTE IN FCB. - 848 ; - 04A6 2Ar43s03 849 SETEXT: LD HL,(PARAMS) - 04A9 11 0C 00 850 LD DE,#12 ; IT IS THE TWELTH BYTE. - 04AC 19 851 ADD HL,DE - 04AD C9 852 RET - 853 ; - 854 ; SET (HL) TO POINT TO RECORD COUNT BYTE IN FCB AND (DE) TO - 855 ; NEXT RECORD NUMBER BYTE. - 856 ; - 04AE 2Ar43s03 857 SETHLDE:LD HL,(PARAMS) - 04B1 11 0F 00 858 LD DE,#15 ; RECORD COUNT BYTE (#15). - 04B4 19 859 ADD HL,DE - 04B5 EB 860 EX DE,HL - 04B6 21 11 00 861 LD HL,#17 ; NEXT RECORD NUMBER (#32). - 04B9 19 862 ADD HL,DE - 04BA C9 863 RET - 864 ; - 865 ; SAVE CURRENT FILE DATA FROM FCB. - 866 ; - 04BB CDrAEs04 867 STRDATA:CALL SETHLDE - 04BE 7E 868 LD A,(HL) ; GET AND STORE RECORD COUNT BYTE. - 04BF 32rE3s0D 869 LD (SAVNREC),A - 04C2 EB 870 EX DE,HL - 04C3 7E 871 LD A,(HL) ; GET AND STORE NEXT RECORD NUMBER BYTE. - 04C4 32rE1s0D 872 LD (SAVNXT),A - 04C7 CDrA6s04 873 CALL SETEXT ; POINT TO EXTENT BYTE. - 04CA 3ArC5s0D 874 LD A,(EXTMASK) ; GET EXTENT MASK. - 04CD A6 875 AND (HL) - 04CE 32rE2s0D 876 LD (SAVEXT),A ; AND SAVE EXTENT HERE. - 04D1 C9 877 RET - 878 ; - 879 ; SET THE NEXT RECORD TO ACCESS. IF (MODE) IS SET TO 2, THEN - 880 ; THE LAST RECORD BYTE (SAVNREC) HAS THE CORRECT NUMBER TO ACCESS. - 881 ; FOR S.EQUENTIAL ACCESS, (MODE) WILL BE .EQUAL TO 1. - 882 ; - 04D2 CDrAEs04 883 SETNREC:CALL SETHLDE - 04D5 3ArD5s0D 884 LD A,(MODE) ; GET S.EQUENTIAL FLAG (=1). - 04D8 FE 02 885 CP #2 ; A 2 INDICATES THAT NO ADDER IS NEEDED. - 04DA C2rDEs04 886 JP NZ,STNREC1 - 04DD AF 887 XOR A ; CLEAR ADDER (RANDOM ACCESS?). - 04DE 4F 888 STNREC1:LD C,A - 04DF 3ArE3s0D 889 LD A,(SAVNREC) ; GET LAST RECORD NUMBER. - 04E2 81 890 ADD A,C ; INCREMENT RECORD COUNT. - 04E3 77 891 LD (HL),A ; AND SET FCB'S NEXT RECORD BYTE. - 04E4 EB 892 EX DE,HL - 04E5 3ArE1s0D 893 LD A,(SAVNXT) ; GET NEXT RECORD BYTE FROM STORAGE. - 04E8 77 894 LD (HL),A ; AND PUT THIS INTO FCB AS NUMBER OF RECORDS USED. - 04E9 C9 895 RET - 896 ; - 897 ; SHIFT (HL) RIGHT (C) BITS. - 898 ; - 04EA 0C 899 SHIFTR: INC C - 04EB 0D 900 SHIFTR1:DEC C - 04EC C8 901 RET Z - 04ED 7C 902 LD A,H - 04EE B7 903 OR A - 04EF 1F 904 RRA - 04F0 67 905 LD H,A - 04F1 7D 906 LD A,L - 04F2 1F 907 RRA - 04F3 6F 908 LD L,A - 04F4 C3rEBs04 909 JP SHIFTR1 - 910 ; - 911 ; COMPUTE THE CHECK-SUM FOR THE DIRECTORY BUFFER. RETURN - 912 ; INTEGER SUM IN (A). - 913 ; - 04F7 914 CHECKSUM: - 04F7 0E 80 915 LD C,#128 ; LENGTH OF BUFFER. - 04F9 2ArB9s0D 916 LD HL,(DIRBUF) ; GET ITS LOCATION. - 04FC AF 917 XOR A ; CLEAR SUMMATION BYTE. - 04FD 86 918 CHKSUM1:ADD A,(HL) ; AND COMPUTE SUM IGNORING CARRIES. - 04FE 23 919 INC HL - 04FF 0D 920 DEC C - 0500 C2rFDs04 921 JP NZ,CHKSUM1 - 0503 C9 922 RET - 923 ; - 924 ; SHIFT (HL) LEFT (C) BITS. - 925 ; - 0504 0C 926 SHIFTL: INC C - 0505 0D 927 SHIFTL1:DEC C - 0506 C8 928 RET Z - 0507 29 929 ADD HL,HL ; SHIFT LEFT 1 BIT. - 0508 C3r05s05 930 JP SHIFTL1 - 931 ; - 932 ; ROUTINE TO SET A BIT IN A 16 BIT VALUE CONTAINED IN (BC). - 933 ; THE BIT SET DEPENDS ON THE CURRENT DRIVE SELECTION. - 934 ; - 050B C5 935 SETBIT: PUSH BC ; SAVE 16 BIT WORD. - 050C 3Ar42s03 936 LD A,(ACTIVE) ; GET ACTIVE DRIVE. - 050F 4F 937 LD C,A - 0510 21 01 00 938 LD HL,#1 - 0513 CDr04s05 939 CALL SHIFTL ; SHIFT BIT 0 INTO PLACE. - 0516 C1 940 POP BC ; NOW 'OR' THIS WITH THE ORIGINAL WORD. - 0517 79 941 LD A,C - 0518 B5 942 OR L - 0519 6F 943 LD L,A ; LOW BYTE DONE, DO HIGH BYTE. - 051A 78 944 LD A,B - 051B B4 945 OR H - 051C 67 946 LD H,A - 051D C9 947 RET - 948 ; - 949 ; EXTRACT THE WRITE PROTECT STATUS BIT FOR THE CURRENT DRIVE. - 950 ; THE RESULT IS RETURNED IN (A), BIT 0. - 951 ; - 051E 2ArADs0D 952 GETWPRT:LD HL,(WRTPRT) ; GET STATUS BYTES. - 0521 3Ar42s03 953 LD A,(ACTIVE) ; WHICH DRIVE IS CURRENT? - 0524 4F 954 LD C,A - 0525 CDrEAs04 955 CALL SHIFTR ; SHIFT STATUS SUCH THAT BIT 0 IS THE - 0528 7D 956 LD A,L ; ONE OF INTEREST FOR THIS DRIVE. - 0529 E6 01 957 AND #1 ; AND ISOLATE IT. - 052B C9 958 RET - 959 ; - 960 ; FUNCTION TO WRITE PROTECT THE CURRENT DISK. - 961 ; - 052C 21rADs0D 962 WRTPRTD:LD HL,#WRTPRT ; POINT TO STATUS WORD. - 052F 4E 963 LD C,(HL) ; SET (BC) .EQUAL TO THE STATUS. - 0530 23 964 INC HL - 0531 46 965 LD B,(HL) - 0532 CDr0Bs05 966 CALL SETBIT ; AND SET THIS BIT ACCORDING TO CURRENT DRIVE. - 0535 22rADs0D 967 LD (WRTPRT),HL ; THEN SAVE. - 0538 2ArC8s0D 968 LD HL,(DIRSIZE) ; NOW SAVE DIRECTORY SIZE LIMIT. - 053B 23 969 INC HL ; REMEMBER THE LAST ONE. - 053C EB 970 EX DE,HL - 053D 2ArB3s0D 971 LD HL,(SCRATCH1) ; AND STORE IT HERE. - 0540 73 972 LD (HL),E ; PUT LOW BYTE. - 0541 23 973 INC HL - 0542 72 974 LD (HL),D ; THEN HIGH BYTE. - 0543 C9 975 RET - 976 ; - 977 ; CHECK FOR A READ ONLY FILE. - 978 ; - 0544 CDr5Es05 979 CHKROFL:CALL FCB2HL ; SET (HL) TO FILE ENTRY IN DIRECTORY BUFFER. - 0547 11 09 00 980 CKROF1: LD DE,#9 ; LOOK AT BIT 7 OF THE NINTH BYTE. - 054A 19 981 ADD HL,DE - 054B 7E 982 LD A,(HL) - 054C 17 983 RLA - 054D D0 984 RET NC ; RETURN IF OK. - 054E 21r0Fs00 985 LD HL,#ROFILE ; ELSE, PRINT ERROR MESSAGE AND TERMINATE. - 0551 C3r4As03 986 JP JUMPHL - 987 ; - 988 ; CHECK THE WRITE PROTECT STATUS OF THE ACTIVE DISK. - 989 ; - 0554 CDr1Es05 990 CHKWPRT:CALL GETWPRT - 0557 C8 991 RET Z ; RETURN IF OK. - 0558 21r0Ds00 992 LD HL,#RODISK ; ELSE PRINT MESSAGE AND TERMINATE. - 055B C3r4As03 993 JP JUMPHL - 994 ; - 995 ; ROUTINE TO SET (HL) POINTING TO THE PROPER ENTRY IN THE - 996 ; DIRECTORY BUFFER. - 997 ; - 055E 2ArB9s0D 998 FCB2HL: LD HL,(DIRBUF) ; GET ADDRESS OF BUFFER. - 0561 3ArE9s0D 999 LD A,(FCBPOS) ; RELATIVE POSITION OF FILE. - 1000 ; - 1001 ; ROUTINE TO ADD (A) TO (HL). - 1002 ; - 0564 85 1003 ADDA2HL:ADD A,L - 0565 6F 1004 LD L,A - 0566 D0 1005 RET NC - 0567 24 1006 INC H ; TAKE CARE OF ANY CARRY. - 0568 C9 1007 RET - 1008 ; - 1009 ; ROUTINE TO GET THE 'S2' BYTE FROM THE FCB SUPPLIED IN - 1010 ; THE INITIAL PARAMETER SPECIFICATION. - 1011 ; - 0569 2Ar43s03 1012 GETS2: LD HL,(PARAMS) ; GET ADDRESS OF FCB. - 056C 11 0E 00 1013 LD DE,#14 ; RELATIVE POSITION OF 'S2'. - 056F 19 1014 ADD HL,DE - 0570 7E 1015 LD A,(HL) ; EXTRACT THIS BYTE. - 0571 C9 1016 RET - 1017 ; - 1018 ; CLEAR THE 'S2' BYTE IN THE FCB. - 1019 ; - 0572 CDr69s05 1020 CLEARS2:CALL GETS2 ; THIS SETS (HL) POINTING TO IT. - 0575 36 00 1021 LD (HL),#0 ; NOW CLEAR IT. - 0577 C9 1022 RET - 1023 ; - 1024 ; SET BIT 7 IN THE 'S2' BYTE OF THE FCB. - 1025 ; - 0578 CDr69s05 1026 SETS2B7:CALL GETS2 ; GET THE BYTE. - 057B F6 80 1027 OR #0x80 ; AND SET BIT 7. - 057D 77 1028 LD (HL),A ; THEN STORE. - 057E C9 1029 RET - 1030 ; - 1031 ; COMPARE (FILEPOS) WITH (SCRATCH1) AND SET FLAGS BASED ON - 1032 ; THE DIFFERENCE. THIS CHECKS TO SEE IF THERE ARE MORE FILE - 1033 ; NAMES IN THE DIRECTORY. WE ARE AT (FILEPOS) AND THERE ARE - 1034 ; (SCRATCH1) OF THEM TO CHECK. - 1035 ; - 057F 2ArEAs0D 1036 MOREFLS:LD HL,(FILEPOS) ; WE ARE HERE. - 0582 EB 1037 EX DE,HL - 0583 2ArB3s0D 1038 LD HL,(SCRATCH1) ; AND DON'T GO PAST HERE. - 0586 7B 1039 LD A,E ; COMPUTE DIFFERENCE BUT DON'T KEEP. - 0587 96 1040 SUB (HL) - 0588 23 1041 INC HL - 0589 7A 1042 LD A,D - 058A 9E 1043 SBC A,(HL) ; SET CARRY IF NO MORE NAMES. - 058B C9 1044 RET - 1045 ; - 1046 ; CALL THIS ROUTINE TO PREVENT (SCRATCH1) FROM BEING GREATER - 1047 ; THAN (FILEPOS). - 1048 ; - 058C CDr7Fs05 1049 CHKNMBR:CALL MOREFLS ; SCRATCH1 TOO BIG? - 058F D8 1050 RET C - 0590 13 1051 INC DE ; YES, RESET IT TO (FILEPOS). - 0591 72 1052 LD (HL),D - 0592 2B 1053 DEC HL - 0593 73 1054 LD (HL),E - 0594 C9 1055 RET - 1056 ; - 1057 ; COMPUTE (HL)=(DE)-(HL) - 1058 ; - 0595 7B 1059 SUBHL: LD A,E ; COMPUTE DIFFERENCE. - 0596 95 1060 SUB L - 0597 6F 1061 LD L,A ; STORE LOW BYTE. - 0598 7A 1062 LD A,D - 0599 9C 1063 SBC A,H - 059A 67 1064 LD H,A ; AND THEN HIGH BYTE. - 059B C9 1065 RET - 1066 ; - 1067 ; SET THE DIRECTORY CHECKSUM BYTE. - 1068 ; - 059C 0E FF 1069 SETDIR: LD C,#0xFF - 1070 ; - 1071 ; ROUTINE TO SET OR COMPARE THE DIRECTORY CHECKSUM BYTE. IF - 1072 ; (C)=0FFH, THEN THIS WILL SET THE CHECKSUM BYTE. ELSE THE BYTE - 1073 ; WILL BE CHECKED. IF THE CHECK FAILS (THE DISK HAS BEEN CHANGED), - 1074 ; THEN THIS DISK WILL BE WRITE PROTECTED. - 1075 ; - 059E 1076 CHECKDIR: - 059E 2ArECs0D 1077 LD HL,(CKSUMTBL) - 05A1 EB 1078 EX DE,HL - 05A2 2ArCCs0D 1079 LD HL,(ALLOC1) - 05A5 CDr95s05 1080 CALL SUBHL - 05A8 D0 1081 RET NC ; OK IF (CKSUMTBL) > (ALLOC1), SO RETURN. - 05A9 C5 1082 PUSH BC - 05AA CDrF7s04 1083 CALL CHECKSUM ; ELSE COMPUTE CHECKSUM. - 05AD 2ArBDs0D 1084 LD HL,(CHKVECT) ; GET ADDRESS OF CHECKSUM TABLE. - 05B0 EB 1085 EX DE,HL - 05B1 2ArECs0D 1086 LD HL,(CKSUMTBL) - 05B4 19 1087 ADD HL,DE ; SET (HL) TO POINT TO BYTE FOR THIS DRIVE. - 05B5 C1 1088 POP BC - 05B6 0C 1089 INC C ; SET OR CHECK ? - 05B7 CArC4s05 1090 JP Z,CHKDIR1 - 05BA BE 1091 CP (HL) ; CHECK THEM. - 05BB C8 1092 RET Z ; RETURN IF THEY ARE THE SAME. - 05BC CDr7Fs05 1093 CALL MOREFLS ; NOT THE SAME, DO WE CARE? - 05BF D0 1094 RET NC - 05C0 CDr2Cs05 1095 CALL WRTPRTD ; YES, MARK THIS AS WRITE PROTECTED. - 05C3 C9 1096 RET - 05C4 77 1097 CHKDIR1:LD (HL),A ; JUST SET THE BYTE. - 05C5 C9 1098 RET - 1099 ; - 1100 ; DO A WRITE TO THE DIRECTORY OF THE CURRENT DISK. - 1101 ; - 05C6 1102 DIRWRITE: - 05C6 CDr9Cs05 1103 CALL SETDIR ; SET CHECKSUM BYTE. - 05C9 CDrE0s05 1104 CALL DIRDMA ; SET DIRECTORY DMA ADDRESS. - 05CC 0E 01 1105 LD C,#1 ; TELL THE BIOS TO ACTUALLY WRITE. - 05CE CDrB8s03 1106 CALL DOWRITE ; THEN DO THE WRITE. - 05D1 C3rDAs05 1107 JP DEFDMA - 1108 ; - 1109 ; READ FROM THE DIRECTORY. - 1110 ; - 05D4 CDrE0s05 1111 DIRREAD:CALL DIRDMA ; SET THE DIRECTORY DMA ADDRESS. - 05D7 CDrB2s03 1112 CALL DOREAD ; AND READ IT. - 1113 ; - 1114 ; ROUTINE TO SET THE DMA ADDRESS TO THE USERS CHOICE. - 1115 ; - 05DA 21rB1s0D 1116 DEFDMA: LD HL,#USERDMA ; RESET THE DEFAULT DMA ADDRESS AND RETURN. - 05DD C3rE3s05 1117 JP DIRDMA1 - 1118 ; - 1119 ; ROUTINE TO SET THE DMA ADDRESS FOR DIRECTORY WORK. - 1120 ; - 05E0 21rB9s0D 1121 DIRDMA: LD HL,#DIRBUF - 1122 ; - 1123 ; SET THE DMA ADDRESS. ON ENTRY, (HL) POINTS TO - 1124 ; WORD CONTAINING THE DESIRED DMA ADDRESS. - 1125 ; - 05E3 4E 1126 DIRDMA1:LD C,(HL) - 05E4 23 1127 INC HL - 05E5 46 1128 LD B,(HL) ; SETUP (BC) AND GO TO THE BIOS TO SET IT. - 05E6 C3 24 E6 1129 JP SETDMA - 1130 ; - 1131 ; MOVE THE DIRECTORY BUFFER INTO USER'S DMA SPACE. - 1132 ; - 05E9 2ArB9s0D 1133 MOVEDIR:LD HL,(DIRBUF) ; BUFFER IS LOCATED HERE, AND - 05EC EB 1134 EX DE,HL - 05ED 2ArB1s0D 1135 LD HL,(USERDMA) ; PUT IT HERE. - 05F0 0E 80 1136 LD C,#128 ; THIS IS ITS LENGTH. - 05F2 C3r4Fs03 1137 JP DE2HL ; MOVE IT NOW AND RETURN. - 1138 ; - 1139 ; CHECK (FILEPOS) AND SET THE ZERO FLAG IF IT .EQUALS 0FFFFH. - 1140 ; - 05F5 1141 CKFILPOS: - 05F5 21rEAs0D 1142 LD HL,#FILEPOS - 05F8 7E 1143 LD A,(HL) - 05F9 23 1144 INC HL - 05FA BE 1145 CP (HL) ; ARE BOTH BYTES THE SAME? - 05FB C0 1146 RET NZ - 05FC 3C 1147 INC A ; YES, BUT ARE THEY EACH 0FFH? - 05FD C9 1148 RET - 1149 ; - 1150 ; SET LOCATION (FILEPOS) TO 0FFFFH. - 1151 ; - 05FE 1152 STFILPOS: - 05FE 21 FF FF 1153 LD HL,#0x0FFFF - 0601 22rEAs0D 1154 LD (FILEPOS),HL - 0604 C9 1155 RET - 1156 ; - 1157 ; MOVE ON TO THE NEXT FILE POSITION WITHIN THE CURRENT - 1158 ; DIRECTORY BUFFER. IF NO MORE EXIST, SET POINTER TO 0FFFFH - 1159 ; AND THE CALLING ROUTINE WILL CHECK FOR THIS. ENTER WITH (C) - 1160 ; .EQUAL TO 0FFH TO CAUSE THE CHECKSUM BYTE TO BE SET, ELSE WE - 1161 ; WILL CHECK THIS DISK AND SET WRITE PROTECT IF CHECKSUMS ARE - 1162 ; NOT THE SAME (APPLIES ONLY IF ANOTHER DIRECTORY SECTOR MUST - 1163 ; BE READ). - 1164 ; - 0605 2ArC8s0D 1165 NXENTRY:LD HL,(DIRSIZE) ; GET DIRECTORY ENTRY SIZE LIMIT. - 0608 EB 1166 EX DE,HL - 0609 2ArEAs0D 1167 LD HL,(FILEPOS) ; GET CURRENT COUNT. - 060C 23 1168 INC HL ; GO ON TO THE NEXT ONE. - 060D 22rEAs0D 1169 LD (FILEPOS),HL - 0610 CDr95s05 1170 CALL SUBHL ; (HL)=(DIRSIZE)-(FILEPOS) - 0613 D2r19s06 1171 JP NC,NXENT1 ; IS THERE MORE ROOM LEFT? - 0616 C3rFEs05 1172 JP STFILPOS ; NO. SET THIS FLAG AND RETURN. - 0619 3ArEAs0D 1173 NXENT1: LD A,(FILEPOS) ; GET FILE POSITION WITHIN DIRECTORY. - 061C E6 03 1174 AND #3 ; ONLY LOOK WITHIN THIS SECTOR (ONLY 4 ENTRIES FIT). - 061E 06 05 1175 LD B,#5 ; CONVERT TO RELATIVE POSITION (32 BYTES EACH). - 0620 87 1176 NXENT2: ADD A,A ; NOTE THAT THIS IS NOT EFFICIENT CODE. - 0621 05 1177 DEC B ; 5 'ADD A'S WOULD BE BETTER. - 0622 C2r20s06 1178 JP NZ,NXENT2 - 0625 32rE9s0D 1179 LD (FCBPOS),A ; SAVE IT AS POSITION OF FCB. - 0628 B7 1180 OR A - 0629 C0 1181 RET NZ ; RETURN IF WE ARE WITHIN BUFFER. - 062A C5 1182 PUSH BC - 062B CDrC3s03 1183 CALL TRKSEC ; WE NEED THE NEXT DIRECTORY SECTOR. - 062E CDrD4s05 1184 CALL DIRREAD - 0631 C1 1185 POP BC - 0632 C3r9Es05 1186 JP CHECKDIR - 1187 ; - 1188 ; ROUTINE TO TO GET A BIT FROM THE DISK SPACE ALLOCATION - 1189 ; MAP. IT IS RETURNED IN (A), BIT POSITION 0. ON ENTRY TO HERE, - 1190 ; SET (BC) TO THE BLOCK NUMBER ON THE DISK TO CHECK. - 1191 ; ON RETURN, (D) WILL CONTAIN THE ORIGINAL BIT POSITION FOR - 1192 ; THIS BLOCK NUMBER AND (HL) WILL POINT TO THE ADDRESS FOR IT. - 1193 ; - 0635 1194 CKBITMAP: - 0635 79 1195 LD A,C ; DETERMINE BIT NUMBER OF INTEREST. - 0636 E6 07 1196 AND #7 ; COMPUTE (D)=(E)=(C AND 7)+1. - 0638 3C 1197 INC A - 0639 5F 1198 LD E,A ; SAVE PARTICULAR BIT NUMBER. - 063A 57 1199 LD D,A - 1200 ; - 1201 ; COMPUTE (BC)=(BC)/8. - 1202 ; - 063B 79 1203 LD A,C - 063C 0F 1204 RRCA ; NOW SHIFT RIGHT 3 BITS. - 063D 0F 1205 RRCA - 063E 0F 1206 RRCA - 063F E6 1F 1207 AND #0x1F ; AND CLEAR BITS 7,6,5. - 0641 4F 1208 LD C,A - 0642 78 1209 LD A,B - 0643 87 1210 ADD A,A ; NOW SHIFT (B) INTO BITS 7,6,5. - 0644 87 1211 ADD A,A - 0645 87 1212 ADD A,A - 0646 87 1213 ADD A,A - 0647 87 1214 ADD A,A - 0648 B1 1215 OR C ; AND ADD IN (C). - 0649 4F 1216 LD C,A ; OK, (C) HA BEEN COMPLETED. - 064A 78 1217 LD A,B ; IS THERE A BETTER WAY OF DOING THIS? - 064B 0F 1218 RRCA - 064C 0F 1219 RRCA - 064D 0F 1220 RRCA - 064E E6 1F 1221 AND #0x1F - 0650 47 1222 LD B,A ; AND NOW (B) IS COMPLETED. - 1223 ; - 1224 ; USE THIS AS AN OFFSET INTO THE DISK SPACE ALLOCATION - 1225 ; TABLE. - 1226 ; - 0651 2ArBFs0D 1227 LD HL,(ALOCVECT) - 0654 09 1228 ADD HL,BC - 0655 7E 1229 LD A,(HL) ; NOW GET CORRECT BYTE. - 0656 07 1230 CKBMAP1:RLCA ; GET CORRECT BIT INTO POSITION 0. - 0657 1D 1231 DEC E - 0658 C2r56s06 1232 JP NZ,CKBMAP1 - 065B C9 1233 RET - 1234 ; - 1235 ; SET OR CLEAR THE BIT MAP SUCH THAT BLOCK NUMBER (BC) WILL BE MARKED - 1236 ; AS USED. ON ENTRY, IF (E)=0 THEN THIS BIT WILL BE CLEARED, IF IT .EQUALS - 1237 ; 1 THEN IT WILL BE SET (DON'T USE ANYOTHER VALUES). - 1238 ; - 065C 1239 STBITMAP: - 065C D5 1240 PUSH DE - 065D CDr35s06 1241 CALL CKBITMAP ; GET THE BYTE OF INTEREST. - 0660 E6 FE 1242 AND #0x0FE ; CLEAR THE AFFECTED BIT. - 0662 C1 1243 POP BC - 0663 B1 1244 OR C ; AND NOW SET IT ACORDING TO (C). - 1245 ; - 1246 ; ENTRY TO RESTORE THE ORIGINAL BIT POSITION AND THEN STORE - 1247 ; IN TABLE. (A) CONTAINS THE VALUE, (D) CONTAINS THE BIT - 1248 ; POSITION (1-8), AND (HL) POINTS TO THE ADDRESS WITHIN THE - 1249 ; SPACE ALLOCATION TABLE FOR THIS BYTE. - 1250 ; - 0664 0F 1251 STBMAP1:RRCA ; RESTORE ORIGINAL BIT POSITION. - 0665 15 1252 DEC D - 0666 C2r64s06 1253 JP NZ,STBMAP1 - 0669 77 1254 LD (HL),A ; AND STOR BYTE IN TABLE. - 066A C9 1255 RET - 1256 ; - 1257 ; SET/CLEAR SPACE USED BITS IN ALLOCATION MAP FOR THIS FILE. - 1258 ; ON ENTRY, (C)=1 TO SET THE MAP AND (C)=0 TO CLEAR IT. - 1259 ; - 066B CDr5Es05 1260 SETFILE:CALL FCB2HL ; GET ADDRESS OF FCB - 066E 11 10 00 1261 LD DE,#16 - 0671 19 1262 ADD HL,DE ; GET TO BLOCK NUMBER BYTES. - 0672 C5 1263 PUSH BC - 0673 0E 11 1264 LD C,#17 ; CHECK ALL 17 BYTES (MAX) OF TABLE. - 0675 D1 1265 SETFL1: POP DE - 0676 0D 1266 DEC C ; DONE ALL BYTES YET? - 0677 C8 1267 RET Z - 0678 D5 1268 PUSH DE - 0679 3ArDDs0D 1269 LD A,(BIGDISK) ; CHECK DISK SIZE FOR 16 BIT BLOCK NUMBERS. - 067C B7 1270 OR A - 067D CAr88s06 1271 JP Z,SETFL2 - 0680 C5 1272 PUSH BC ; ONLY 8 BIT NUMBERS. SET (BC) TO THIS ONE. - 0681 E5 1273 PUSH HL - 0682 4E 1274 LD C,(HL) ; GET LOW BYTE FROM TABLE, ALWAYS - 0683 06 00 1275 LD B,#0 ; SET HIGH BYTE TO ZERO. - 0685 C3r8Es06 1276 JP SETFL3 - 0688 0D 1277 SETFL2: DEC C ; FOR 16 BIT BLOCK NUMBERS, ADJUST COUNTER. - 0689 C5 1278 PUSH BC - 068A 4E 1279 LD C,(HL) ; NOW GET BOTH THE LOW AND HIGH BYTES. - 068B 23 1280 INC HL - 068C 46 1281 LD B,(HL) - 068D E5 1282 PUSH HL - 068E 79 1283 SETFL3: LD A,C ; BLOCK USED? - 068F B0 1284 OR B - 0690 CAr9Ds06 1285 JP Z,SETFL4 - 0693 2ArC6s0D 1286 LD HL,(DSKSIZE) ; IS THIS BLOCK NUMBER WITHIN THE - 0696 7D 1287 LD A,L ; SPACE ON THE DISK? - 0697 91 1288 SUB C - 0698 7C 1289 LD A,H - 0699 98 1290 SBC A,B - 069A D4r5Cs06 1291 CALL NC,STBITMAP ; YES, SET THE PROPER BIT. - 069D E1 1292 SETFL4: POP HL ; POINT TO NEXT BLOCK NUMBER IN FCB. - 069E 23 1293 INC HL - 069F C1 1294 POP BC - 06A0 C3r75s06 1295 JP SETFL1 - 1296 ; - 1297 ; CONSTRUCT THE SPACE USED ALLOCATION BIT MAP FOR THE ACTIVE - 1298 ; DRIVE. IF A FILE NAME STARTS WITH '$' AND IT IS UNDER THE - 1299 ; CURRENT USER NUMBER, THEN (STATUS) IS SET TO MINUS 1. OTHERWISE - 1300 ; IT IS NOT SET AT ALL. - 1301 ; - 06A3 2ArC6s0D 1302 BITMAP: LD HL,(DSKSIZE) ; COMPUTE SIZE OF ALLOCATION TABLE. - 06A6 0E 03 1303 LD C,#3 - 06A8 CDrEAs04 1304 CALL SHIFTR ; (HL)=(HL)/8. - 06AB 23 1305 INC HL ; AT LEASE 1 BYTE. - 06AC 44 1306 LD B,H - 06AD 4D 1307 LD C,L ; SET (BC) TO THE ALLOCATION TABLE LENGTH. - 1308 ; - 1309 ; INITIALIZE THE BITMAP FOR THIS DRIVE. RIGHT NOW, THE FIRST - 1310 ; TWO BYTES ARE SPECIFIED BY THE DISK PARAMETER BLOCK. HOWEVER - 1311 ; A PATCH COULD BE ENTERED HERE IF IT WERE NECESSARY TO SETUP - 1312 ; THIS TABLE IN A SPECIAL MANNOR. FOR EXAMPLE, THE BIOS COULD - 1313 ; DETERMINE LOCATIONS OF 'BAD BLOCKS' AND SET THEM AS ALREADY - 1314 ; 'USED' IN THE MAP. - 1315 ; - 06AE 2ArBFs0D 1316 LD HL,(ALOCVECT) ; NOW ZERO OUT THE TABLE NOW. - 06B1 36 00 1317 BITMAP1:LD (HL),#0 - 06B3 23 1318 INC HL - 06B4 0B 1319 DEC BC - 06B5 78 1320 LD A,B - 06B6 B1 1321 OR C - 06B7 C2rB1s06 1322 JP NZ,BITMAP1 - 06BA 2ArCAs0D 1323 LD HL,(ALLOC0) ; GET INITIAL SPACE USED BY DIRECTORY. - 06BD EB 1324 EX DE,HL - 06BE 2ArBFs0D 1325 LD HL,(ALOCVECT) ; AND PUT THIS INTO MAP. - 06C1 73 1326 LD (HL),E - 06C2 23 1327 INC HL - 06C3 72 1328 LD (HL),D - 1329 ; - 1330 ; END OF INITIALIZATION PORTION. - 1331 ; - 06C4 CDrA1s03 1332 CALL HOMEDRV ; NOW HOME THE DRIVE. - 06C7 2ArB3s0D 1333 LD HL,(SCRATCH1) - 06CA 36 03 1334 LD (HL),#3 ; FORCE NEXT DIRECTORY R.EQUEST TO READ - 06CC 23 1335 INC HL ; IN A SECTOR. - 06CD 36 00 1336 LD (HL),#0 - 06CF CDrFEs05 1337 CALL STFILPOS ; CLEAR INITIAL FILE POSITION ALSO. - 06D2 0E FF 1338 BITMAP2:LD C,#0x0FF ; READ NEXT FILE NAME IN DIRECTORY - 06D4 CDr05s06 1339 CALL NXENTRY ; AND SET CHECKSUM BYTE. - 06D7 CDrF5s05 1340 CALL CKFILPOS ; IS THERE ANOTHER FILE? - 06DA C8 1341 RET Z - 06DB CDr5Es05 1342 CALL FCB2HL ; YES, GET ITS ADDRESS. - 06DE 3E E5 1343 LD A,#0x0E5 - 06E0 BE 1344 CP (HL) ; EMPTY FILE ENTRY? - 06E1 CArD2s06 1345 JP Z,BITMAP2 - 06E4 3Ar41s03 1346 LD A,(USERNO) ; NO, CORRECT USER NUMBER? - 06E7 BE 1347 CP (HL) - 06E8 C2rF6s06 1348 JP NZ,BITMAP3 - 06EB 23 1349 INC HL - 06EC 7E 1350 LD A,(HL) ; YES, DOES NAME START WITH A '$'? - 06ED D6 24 1351 SUB #DOLLAR - 06EF C2rF6s06 1352 JP NZ,BITMAP3 - 06F2 3D 1353 DEC A ; YES, SET ATATUS TO MINUS ONE. - 06F3 32r45s03 1354 LD (STATUS),A - 06F6 0E 01 1355 BITMAP3:LD C,#1 ; NOW SET THIS FILE'S SPACE AS USED IN BIT MAP. - 06F8 CDr6Bs06 1356 CALL SETFILE - 06FB CDr8Cs05 1357 CALL CHKNMBR ; KEEP (SCRATCH1) IN BOUNDS. - 06FE C3rD2s06 1358 JP BITMAP2 - 1359 ; - 1360 ; SET THE STATUS (STATUS) AND RETURN. - 1361 ; - 0701 1362 STSTATUS: - 0701 3ArD4s0D 1363 LD A,(FNDSTAT) - 0704 C3r01s03 1364 JP SETSTAT - 1365 ; - 1366 ; CHECK EXTENTS IN (A) AND (C). SET THE ZERO FLAG IF THEY - 1367 ; ARE THE SAME. THE NUMBER OF 16K CHUNKS OF DISK SPACE THAT - 1368 ; THE DIRECTORY EXTENT COVERS IS EXPRESSAD IS (EXTMASK+1). - 1369 ; NO REGISTERS ARE MODIFIED. - 1370 ; - 0707 C5 1371 SAMEXT: PUSH BC - 0708 F5 1372 PUSH AF - 0709 3ArC5s0D 1373 LD A,(EXTMASK) ; GET EXTENT MASK AND USE IT TO - 070C 2F 1374 CPL ; TO COMPARE BOTH EXTENT NUMBERS. - 070D 47 1375 LD B,A ; SAVE RESULTING MASK HERE. - 070E 79 1376 LD A,C ; MASK FIRST EXTENT AND SAVE IN (C). - 070F A0 1377 AND B - 0710 4F 1378 LD C,A - 0711 F1 1379 POP AF ; NOW MASK SECOND EXTENT AND COMPARE - 0712 A0 1380 AND B ; WITH THE FIRST ONE. - 0713 91 1381 SUB C - 0714 E6 1F 1382 AND #0x1F ; (* ONLY CHECK BUTS 0-4 *) - 0716 C1 1383 POP BC ; THE ZERO FLAG IS SET IF THEY ARE THE SAME. - 0717 C9 1384 RET ; RESTORE (BC) AND RETURN. - 1385 ; - 1386 ; SEARCH FOR THE FIRST OCCURENCE OF A FILE NAME. ON ENTRY, - 1387 ; REGISTER (C) SHOULD CONTAIN THE NUMBER OF BYTES OF THE FCB - 1388 ; THAT MUST MATCH. - 1389 ; - 0718 3E FF 1390 FINDFST:LD A,#0x0FF - 071A 32rD4s0D 1391 LD (FNDSTAT),A - 071D 21rD8s0D 1392 LD HL,#COUNTER ; SAVE CHARACTER COUNT. - 0720 71 1393 LD (HL),C - 0721 2Ar43s03 1394 LD HL,(PARAMS) ; GET FILENAME TO MATCH. - 0724 22rD9s0D 1395 LD (SAVEFCB),HL ; AND SAVE. - 0727 CDrFEs05 1396 CALL STFILPOS ; CLEAR INITIAL FILE POSITION (SET TO 0FFFFH). - 072A CDrA1s03 1397 CALL HOMEDRV ; HOME THE DRIVE. - 1398 ; - 1399 ; ENTRY TO LOCATE THE NEXT OCCURENCE OF A FILENAME WITHIN THE - 1400 ; DIRECTORY. THE DISK IS NOT EXPECTED TO HAVE BEEN CHANGED. IF - 1401 ; IT WAS, THEN IT WILL BE WRITE PROTECTED. - 1402 ; - 072D 0E 00 1403 FINDNXT:LD C,#0 ; WRITE PROTECT THE DISK IF CHANGED. - 072F CDr05s06 1404 CALL NXENTRY ; GET NEXT FILENAME ENTRY IN DIRECTORY. - 0732 CDrF5s05 1405 CALL CKFILPOS ; IS FILE POSITION = 0FFFFH? - 0735 CAr94s07 1406 JP Z,FNDNXT6 ; YES, EXIT NOW THEN. - 0738 2ArD9s0D 1407 LD HL,(SAVEFCB) ; SET (DE) POINTING TO FILENAME TO MATCH. - 073B EB 1408 EX DE,HL - 073C 1A 1409 LD A,(DE) - 073D FE E5 1410 CP #0x0E5 ; EMPTY DIRECTORY ENTRY? - 073F CAr4As07 1411 JP Z,FNDNXT1 ; (* ARE WE TRYING TO RESERECT ERASED ENTRIES? *) - 0742 D5 1412 PUSH DE - 0743 CDr7Fs05 1413 CALL MOREFLS ; MORE FILES IN DIRECTORY? - 0746 D1 1414 POP DE - 0747 D2r94s07 1415 JP NC,FNDNXT6 ; NO MORE. EXIT NOW. - 074A CDr5Es05 1416 FNDNXT1:CALL FCB2HL ; GET ADDRESS OF THIS FCB IN DIRECTORY. - 074D 3ArD8s0D 1417 LD A,(COUNTER) ; GET NUMBER OF BYTES (CHARACTERS) TO CHECK. - 0750 4F 1418 LD C,A - 0751 06 00 1419 LD B,#0 ; INITIALIZE BYTE POSITION COUNTER. - 0753 79 1420 FNDNXT2:LD A,C ; ARE WE DONE WITH THE COMPARE? - 0754 B7 1421 OR A - 0755 CAr83s07 1422 JP Z,FNDNXT5 - 0758 1A 1423 LD A,(DE) ; NO, CHECK NEXT BYTE. - 0759 FE 3F 1424 CP #QUESTION ; DON'T CARE ABOUT THIS CHARACTER? - 075B CAr7Cs07 1425 JP Z,FNDNXT4 - 075E 78 1426 LD A,B ; GET BYTES POSITION IN FCB. - 075F FE 0D 1427 CP #13 ; DON'T CARE ABOUT THE THIRTEENTH BYTE EITHER. - 0761 CAr7Cs07 1428 JP Z,FNDNXT4 - 0764 FE 0C 1429 CP #12 ; EXTENT BYTE? - 0766 1A 1430 LD A,(DE) - 0767 CAr73s07 1431 JP Z,FNDNXT3 - 076A 96 1432 SUB (HL) ; OTHERWISE COMPARE CHARACTERS. - 076B E6 7F 1433 AND #0x7F - 076D C2r2Ds07 1434 JP NZ,FINDNXT ; NOT THE SAME, CHECK NEXT ENTRY. - 0770 C3r7Cs07 1435 JP FNDNXT4 ; SO FAR SO GOOD, KEEP CHECKING. - 0773 C5 1436 FNDNXT3:PUSH BC ; CHECK THE EXTENT BYTE HERE. - 0774 4E 1437 LD C,(HL) - 0775 CDr07s07 1438 CALL SAMEXT - 0778 C1 1439 POP BC - 0779 C2r2Ds07 1440 JP NZ,FINDNXT ; NOT THE SAME, LOOK SOME MORE. - 1441 ; - 1442 ; SO FAR THE NAMES COMPARE. BUMP POINTERS TO THE NEXT BYTE - 1443 ; AND CONTINUE UNTIL ALL (C) CHARACTERS HAVE BEEN CHECKED. - 1444 ; - 077C 13 1445 FNDNXT4:INC DE ; BUMP POINTERS. - 077D 23 1446 INC HL - 077E 04 1447 INC B - 077F 0D 1448 DEC C ; ADJUST CHARACTER COUNTER. - 0780 C3r53s07 1449 JP FNDNXT2 - 0783 3ArEAs0D 1450 FNDNXT5:LD A,(FILEPOS) ; RETURN THE POSITION OF THIS ENTRY. - 0786 E6 03 1451 AND #3 - 0788 32r45s03 1452 LD (STATUS),A - 078B 21rD4s0D 1453 LD HL,#FNDSTAT - 078E 7E 1454 LD A,(HL) - 078F 17 1455 RLA - 0790 D0 1456 RET NC - 0791 AF 1457 XOR A - 0792 77 1458 LD (HL),A - 0793 C9 1459 RET - 1460 ; - 1461 ; FILENAME WAS NOT FOUND. SET APPROPRIATE STATUS. - 1462 ; - 0794 CDrFEs05 1463 FNDNXT6:CALL STFILPOS ; SET (FILEPOS) TO 0FFFFH. - 0797 3E FF 1464 LD A,#0x0FF ; SAY NOT LOCATED. - 0799 C3r01s03 1465 JP SETSTAT - 1466 ; - 1467 ; ERASE FILES FROM THE DIRECTORY. ONLY THE FIRST BYTE OF THE - 1468 ; FCB WILL BE AFFECTED. IT IS SET TO (E5). - 1469 ; - 079C CDr54s05 1470 ERAFILE:CALL CHKWPRT ; IS DISK WRITE PROTECTED? - 079F 0E 0C 1471 LD C,#12 ; ONLY COMPARE FILE NAMES. - 07A1 CDr18s07 1472 CALL FINDFST ; GET FIRST FILE NAME. - 07A4 CDrF5s05 1473 ERAFIL1:CALL CKFILPOS ; ANY FOUND? - 07A7 C8 1474 RET Z ; NOPE, WE MUST BE DONE. - 07A8 CDr44s05 1475 CALL CHKROFL ; IS FILE READ ONLY? - 07AB CDr5Es05 1476 CALL FCB2HL ; NOPE, GET ADDRESS OF FCB AND - 07AE 36 E5 1477 LD (HL),#0x0E5 ; SET FIRST BYTE TO 'EMPTY'. - 07B0 0E 00 1478 LD C,#0 ; CLEAR THE SPACE FROM THE BIT MAP. - 07B2 CDr6Bs06 1479 CALL SETFILE - 07B5 CDrC6s05 1480 CALL DIRWRITE ; NOW WRITE THE DIRECTORY SECTOR BACK OUT. - 07B8 CDr2Ds07 1481 CALL FINDNXT ; FIND THE NEXT FILE NAME. - 07BB C3rA4s07 1482 JP ERAFIL1 ; AND REPEAT PROCESS. - 1483 ; - 1484 ; LOOK THROUGH THE SPACE ALLOCATION MAP (BIT MAP) FOR THE - 1485 ; NEXT AVAILABLE BLOCK. START SEARCHING AT BLOCK NUMBER (BC-1). - 1486 ; THE SEARCH PROCEDURE IS TO LOOK FOR AN EMPTY BLOCK THAT IS - 1487 ; BEFORE THE STARTING BLOCK. IF NOT EMPTY, LOOK AT A LATER - 1488 ; BLOCK NUMBER. IN THIS WAY, WE RETURN THE CLOSEST EMPTY BLOCK - 1489 ; ON EITHER SIDE OF THE 'TARGET' BLOCK NUMBER. THIS WILL SPEED - 1490 ; ACCESS ON RANDOM DEVICES. FOR SERIAL DEVICES, THIS SHOULD BE - 1491 ; CHANGED TO LOOK IN THE FORWARD DIRECTION FIRST AND THEN START - 1492 ; AT THE FRONT AND SEARCH SOME MORE. - 1493 ; - 1494 ; ON RETURN, (DE)= BLOCK NUMBER THAT IS EMPTY AND (HL) =0 - 1495 ; IF NO EMPRY BLOCK WAS FOUND. - 1496 ; - 07BE 1497 FNDSPACE: - 07BE 50 1498 LD D,B ; SET (DE) AS THE BLOCK THAT IS CHECKED. - 07BF 59 1499 LD E,C - 1500 ; - 1501 ; LOOK BEFORE TARGET BLOCK. REGISTERS (BC) ARE USED AS THE LOWER - 1502 ; POINTER AND (DE) AS THE UPPER POINTER. - 1503 ; - 07C0 79 1504 FNDSPA1:LD A,C ; IS BLOCK 0 SPECIFIED? - 07C1 B0 1505 OR B - 07C2 CArD1s07 1506 JP Z,FNDSPA2 - 07C5 0B 1507 DEC BC ; NOPE, CHECK PREVIOUS BLOCK. - 07C6 D5 1508 PUSH DE - 07C7 C5 1509 PUSH BC - 07C8 CDr35s06 1510 CALL CKBITMAP - 07CB 1F 1511 RRA ; IS THIS BLOCK EMPTY? - 07CC D2rECs07 1512 JP NC,FNDSPA3 ; YES. USE THIS. - 1513 ; - 1514 ; NOTE THAT THE ABOVE LOGIC GETS THE FIRST BLOCK THAT IT FINDS - 1515 ; THAT IS EMPTY. THUS A FILE COULD BE WRITTEN 'BACKWARD' MAKING - 1516 ; IT VERY SLOW TO ACCESS. THIS COULD BE CHANGED TO LOOK FOR THE - 1517 ; FIRST EMPTY BLOCK AND THEN CONTINUE UNTIL THE START OF THIS - 1518 ; EMPTY SPACE IS LOCATED AND THEN USED THAT STARTING BLOCK. - 1519 ; THIS SHOULD HELP SPEED UP ACCESS TO SOME FILES ESPECIALLY ON - 1520 ; A WELL USED DISK WITH LOTS OF FAIRLY SMALL 'HOLES'. - 1521 ; - 07CF C1 1522 POP BC ; NOPE, CHECK SOME MORE. - 07D0 D1 1523 POP DE - 1524 ; - 1525 ; NOW LOOK AFTER TARGET BLOCK. - 1526 ; - 07D1 2ArC6s0D 1527 FNDSPA2:LD HL,(DSKSIZE) ; IS BLOCK (DE) WITHIN DISK LIMITS? - 07D4 7B 1528 LD A,E - 07D5 95 1529 SUB L - 07D6 7A 1530 LD A,D - 07D7 9C 1531 SBC A,H - 07D8 D2rF4s07 1532 JP NC,FNDSPA4 - 07DB 13 1533 INC DE ; YES, MOVE ON TO NEXT ONE. - 07DC C5 1534 PUSH BC - 07DD D5 1535 PUSH DE - 07DE 42 1536 LD B,D - 07DF 4B 1537 LD C,E - 07E0 CDr35s06 1538 CALL CKBITMAP ; CHECK IT. - 07E3 1F 1539 RRA ; EMPTY? - 07E4 D2rECs07 1540 JP NC,FNDSPA3 - 07E7 D1 1541 POP DE ; NOPE, CONTINUE SEARCHING. - 07E8 C1 1542 POP BC - 07E9 C3rC0s07 1543 JP FNDSPA1 - 1544 ; - 1545 ; EMPTY BLOCK FOUND. SET IT AS USED AND RETURN WITH (HL) - 1546 ; POINTING TO IT (TRUE?). - 1547 ; - 07EC 17 1548 FNDSPA3:RLA ; RESET BYTE. - 07ED 3C 1549 INC A ; AND SET BIT 0. - 07EE CDr64s06 1550 CALL STBMAP1 ; UPDATE BIT MAP. - 07F1 E1 1551 POP HL ; SET RETURN REGISTERS. - 07F2 D1 1552 POP DE - 07F3 C9 1553 RET - 1554 ; - 1555 ; FREE BLOCK WAS NOT FOUND. IF (BC) IS NOT ZERO, THEN WE HAVE - 1556 ; NOT CHECKED ALL OF THE DISK SPACE. - 1557 ; - 07F4 79 1558 FNDSPA4:LD A,C - 07F5 B0 1559 OR B - 07F6 C2rC0s07 1560 JP NZ,FNDSPA1 - 07F9 21 00 00 1561 LD HL,#0 ; SET 'NOT FOUND' STATUS. - 07FC C9 1562 RET - 1563 ; - 1564 ; MOVE A COMPLETE FCB ENTRY INTO THE DIRECTORY AND WRITE IT. - 1565 ; - 07FD 0E 00 1566 FCBSET: LD C,#0 - 07FF 1E 20 1567 LD E,#32 ; LENGTH OF EACH ENTRY. - 1568 ; - 1569 ; MOVE (E) BYTES FROM THE FCB POINTED TO BY (PARAMS) INTO - 1570 ; FCB IN DIRECTORY STARTING AT RELATIVE BYTE (C). THIS UPDATED - 1571 ; DIRECTORY BUFFER IS THEN WRITTEN TO THE DISK. - 1572 ; - 0801 D5 1573 UPDATE: PUSH DE - 0802 06 00 1574 LD B,#0 ; SET (BC) TO RELATIVE BYTE POSITION. - 0804 2Ar43s03 1575 LD HL,(PARAMS) ; GET ADDRESS OF FCB. - 0807 09 1576 ADD HL,BC ; COMPUTE STARTING BYTE. - 0808 EB 1577 EX DE,HL - 0809 CDr5Es05 1578 CALL FCB2HL ; GET ADDRESS OF FCB TO UPDATE IN DIRECTORY. - 080C C1 1579 POP BC ; SET (C) TO NUMBER OF BYTES TO CHANGE. - 080D CDr4Fs03 1580 CALL DE2HL - 0810 CDrC3s03 1581 UPDATE1:CALL TRKSEC ; DETERMINE THE TRACK AND SECTOR AFFECTED. - 0813 C3rC6s05 1582 JP DIRWRITE ; THEN WRITE THIS SECTOR OUT. - 1583 ; - 1584 ; ROUTINE TO CHANGE THE NAME OF ALL FILES ON THE DISK WITH A - 1585 ; SPECIFIED NAME. THE FCB CONTAINS THE CURRENT NAME AS THE - 1586 ; FIRST 12 CHARACTERS AND THE NEW NAME 16 BYTES INTO THE FCB. - 1587 ; - 0816 1588 CHGNAMES: - 0816 CDr54s05 1589 CALL CHKWPRT ; CHECK FOR A WRITE PROTECTED DISK. - 0819 0E 0C 1590 LD C,#12 ; MATCH FIRST 12 BYTES OF FCB ONLY. - 081B CDr18s07 1591 CALL FINDFST ; GET FIRST NAME. - 081E 2Ar43s03 1592 LD HL,(PARAMS) ; GET ADDRESS OF FCB. - 0821 7E 1593 LD A,(HL) ; GET USER NUMBER. - 0822 11 10 00 1594 LD DE,#16 ; MOVE OVER TO DESIRED NAME. - 0825 19 1595 ADD HL,DE - 0826 77 1596 LD (HL),A ; KEEP SAME USER NUMBER. - 0827 CDrF5s05 1597 CHGNAM1:CALL CKFILPOS ; ANY MATCHING FILE FOUND? - 082A C8 1598 RET Z ; NO, WE MUST BE DONE. - 082B CDr44s05 1599 CALL CHKROFL ; CHECK FOR READ ONLY FILE. - 082E 0E 10 1600 LD C,#16 ; START 16 BYTES INTO FCB. - 0830 1E 0C 1601 LD E,#12 ; AND UPDATE THE FIRST 12 BYTES OF DIRECTORY. - 0832 CDr01s08 1602 CALL UPDATE - 0835 CDr2Ds07 1603 CALL FINDNXT ; GET TE NEXT FILE NAME. - 0838 C3r27s08 1604 JP CHGNAM1 ; AND CONTINUE. - 1605 ; - 1606 ; UPDATE A FILES ATTRIBUTES. THE PROCEDURE IS TO SEARCH FOR - 1607 ; EVERY FILE WITH THE SAME NAME AS SHOWN IN FCB (IGNORING BIT 7) - 1608 ; AND THEN TO UPDATE IT (WHICH INCLUDES BIT 7). NO OTHER CHANGES - 1609 ; ARE MADE. - 1610 ; - 083B 1611 SAVEATTR: - 083B 0E 0C 1612 LD C,#12 ; MATCH FIRST 12 BYTES. - 083D CDr18s07 1613 CALL FINDFST ; LOOK FOR FIRST FILENAME. - 0840 CDrF5s05 1614 SAVATR1:CALL CKFILPOS ; WAS ONE FOUND? - 0843 C8 1615 RET Z ; NOPE, WE MUST BE DONE. - 0844 0E 00 1616 LD C,#0 ; YES, UPDATE THE FIRST 12 BYTES NOW. - 0846 1E 0C 1617 LD E,#12 - 0848 CDr01s08 1618 CALL UPDATE ; UPDATE FILENAME AND WRITE DIRECTORY. - 084B CDr2Ds07 1619 CALL FINDNXT ; AND GET THE NEXT FILE. - 084E C3r40s08 1620 JP SAVATR1 ; THEN CONTINUE UNTIL DONE. - 1621 ; - 1622 ; OPEN A FILE (NAME SPECIFIED IN FCB). - 1623 ; - 0851 0E 0F 1624 OPENIT: LD C,#15 ; COMPARE THE FIRST 15 BYTES. - 0853 CDr18s07 1625 CALL FINDFST ; GET THE FIRST ONE IN DIRECTORY. - 0856 CDrF5s05 1626 CALL CKFILPOS ; ANY AT ALL? - 0859 C8 1627 RET Z - 085A CDrA6s04 1628 OPENIT1:CALL SETEXT ; POINT TO EXTENT BYTE WITHIN USERS FCB. - 085D 7E 1629 LD A,(HL) ; AND GET IT. - 085E F5 1630 PUSH AF ; SAVE IT AND ADDRESS. - 085F E5 1631 PUSH HL - 0860 CDr5Es05 1632 CALL FCB2HL ; POINT TO FCB IN DIRECTORY. - 0863 EB 1633 EX DE,HL - 0864 2Ar43s03 1634 LD HL,(PARAMS) ; THIS IS THE USERS COPY. - 0867 0E 20 1635 LD C,#32 ; MOVE IT INTO USERS SPACE. - 0869 D5 1636 PUSH DE - 086A CDr4Fs03 1637 CALL DE2HL - 086D CDr78s05 1638 CALL SETS2B7 ; SET BIT 7 IN 'S2' BYTE (UNMODIFIED). - 0870 D1 1639 POP DE ; NOW GET THE EXTENT BYTE FROM THIS FCB. - 0871 21 0C 00 1640 LD HL,#12 - 0874 19 1641 ADD HL,DE - 0875 4E 1642 LD C,(HL) ; INTO (C). - 0876 21 0F 00 1643 LD HL,#15 ; NOW GET THE RECORD COUNT BYTE INTO (B). - 0879 19 1644 ADD HL,DE - 087A 46 1645 LD B,(HL) - 087B E1 1646 POP HL ; KEEP THE SAME EXTENT AS THE USER HAD ORIGINALLY. - 087C F1 1647 POP AF - 087D 77 1648 LD (HL),A - 087E 79 1649 LD A,C ; IS IT THE SAME AS IN THE DIRECTORY FCB? - 087F BE 1650 CP (HL) - 0880 78 1651 LD A,B ; IF YES, THEN USE THE SAME RECORD COUNT. - 0881 CAr8Bs08 1652 JP Z,OPENIT2 - 0884 3E 00 1653 LD A,#0 ; IF THE USER SPECIFIED AN EXTENT GREATER THAN - 0886 DAr8Bs08 1654 JP C,OPENIT2 ; THE ONE IN THE DIRECTORY, THEN SET RECORD COUNT TO 0. - 0889 3E 80 1655 LD A,#128 ; OTHERWISE SET TO MAXIMUM. - 088B 2Ar43s03 1656 OPENIT2:LD HL,(PARAMS) ; SET RECORD COUNT IN USERS FCB TO (A). - 088E 11 0F 00 1657 LD DE,#15 - 0891 19 1658 ADD HL,DE ; COMPUTE RELATIVE POSITION. - 0892 77 1659 LD (HL),A ; AND SET THE RECORD COUNT. - 0893 C9 1660 RET - 1661 ; - 1662 ; MOVE TWO BYTES FROM (DE) TO (HL) IF (AND ONLY IF) (HL) - 1663 ; POINT TO A ZERO VALUE (16 BIT). - 1664 ; RETURN WITH ZERO FLAG SET IT (DE) WAS MOVED. REGISTERS (DE) - 1665 ; AND (HL) ARE NOT CHANGED. HOWEVER (A) IS. - 1666 ; - 0894 1667 MOVEWORD: - 0894 7E 1668 LD A,(HL) ; CHECK FOR A ZERO WORD. - 0895 23 1669 INC HL - 0896 B6 1670 OR (HL) ; BOTH BYTES ZERO? - 0897 2B 1671 DEC HL - 0898 C0 1672 RET NZ ; NOPE, JUST RETURN. - 0899 1A 1673 LD A,(DE) ; YES, MOVE TWO BYTES FROM (DE) INTO - 089A 77 1674 LD (HL),A ; THIS ZERO SPACE. - 089B 13 1675 INC DE - 089C 23 1676 INC HL - 089D 1A 1677 LD A,(DE) - 089E 77 1678 LD (HL),A - 089F 1B 1679 DEC DE ; DON'T DISTURB THESE REGISTERS. - 08A0 2B 1680 DEC HL - 08A1 C9 1681 RET - 1682 ; - 1683 ; GET HERE TO CLOSE A FILE SPECIFIED BY (FCB). - 1684 ; - 08A2 AF 1685 CLOSEIT:XOR A ; CLEAR STATUS AND FILE POSITION BYTES. - 08A3 32r45s03 1686 LD (STATUS),A - 08A6 32rEAs0D 1687 LD (FILEPOS),A - 08A9 32rEBs0D 1688 LD (FILEPOS+1),A - 08AC CDr1Es05 1689 CALL GETWPRT ; GET WRITE PROTECT BIT FOR THIS DRIVE. - 08AF C0 1690 RET NZ ; JUST RETURN IF IT IS SET. - 08B0 CDr69s05 1691 CALL GETS2 ; ELSE GET THE 'S2' BYTE. - 08B3 E6 80 1692 AND #0x80 ; AND LOOK AT BIT 7 (FILE UNMODIFIED?). - 08B5 C0 1693 RET NZ ; JUST RETURN IF SET. - 08B6 0E 0F 1694 LD C,#15 ; ELSE LOOK UP THIS FILE IN DIRECTORY. - 08B8 CDr18s07 1695 CALL FINDFST - 08BB CDrF5s05 1696 CALL CKFILPOS ; WAS IT FOUND? - 08BE C8 1697 RET Z ; JUST RETURN IF NOT. - 08BF 01 10 00 1698 LD BC,#16 ; SET (HL) POINTING TO RECORDS USED SECTION. - 08C2 CDr5Es05 1699 CALL FCB2HL - 08C5 09 1700 ADD HL,BC - 08C6 EB 1701 EX DE,HL - 08C7 2Ar43s03 1702 LD HL,(PARAMS) ; DO THE SAME FOR USERS SPECIFIED FCB. - 08CA 09 1703 ADD HL,BC - 08CB 0E 10 1704 LD C,#16 ; THIS MANY BYTES ARE PRESENT IN THIS EXTENT. - 08CD 1705 CLOSEIT1: - 08CD 3ArDDs0D 1706 LD A,(BIGDISK) ; 8 OR 16 BIT RECORD NUMBERS? - 08D0 B7 1707 OR A - 08D1 CArE8s08 1708 JP Z,CLOSEIT4 - 08D4 7E 1709 LD A,(HL) ; JUST 8 BIT. GET ONE FROM USERS FCB. - 08D5 B7 1710 OR A - 08D6 1A 1711 LD A,(DE) ; NOW GET ONE FROM DIRECTORY FCB. - 08D7 C2rDBs08 1712 JP NZ,CLOSEIT2 - 08DA 77 1713 LD (HL),A ; USERS BYTE WAS ZERO. UPDATE FROM DIRECTORY. - 08DB 1714 CLOSEIT2: - 08DB B7 1715 OR A - 08DC C2rE1s08 1716 JP NZ,CLOSEIT3 - 08DF 7E 1717 LD A,(HL) ; DIRECTORIES BYTE WAS ZERO, UPDATE FROM USERS FCB. - 08E0 12 1718 LD (DE),A - 08E1 1719 CLOSEIT3: - 08E1 BE 1720 CP (HL) ; IF NEITHER ONE OF THESE BYTES WERE ZERO, - 08E2 C2r1Fs09 1721 JP NZ,CLOSEIT7 ; THEN CLOSE ERROR IF THEY ARE NOT THE SAME. - 08E5 C3rFDs08 1722 JP CLOSEIT5 ; OK SO FAR, GET TO NEXT BYTE IN FCBS. - 08E8 1723 CLOSEIT4: - 08E8 CDr94s08 1724 CALL MOVEWORD ; UPDATE USERS FCB IF IT IS ZERO. - 08EB EB 1725 EX DE,HL - 08EC CDr94s08 1726 CALL MOVEWORD ; UPDATE DIRECTORIES FCB IF IT IS ZERO. - 08EF EB 1727 EX DE,HL - 08F0 1A 1728 LD A,(DE) ; IF THESE TWO VALUES ARE NO DIFFERENT, - 08F1 BE 1729 CP (HL) ; THEN A CLOSE ERROR OCCURED. - 08F2 C2r1Fs09 1730 JP NZ,CLOSEIT7 - 08F5 13 1731 INC DE ; CHECK SECOND BYTE. - 08F6 23 1732 INC HL - 08F7 1A 1733 LD A,(DE) - 08F8 BE 1734 CP (HL) - 08F9 C2r1Fs09 1735 JP NZ,CLOSEIT7 - 08FC 0D 1736 DEC C ; REMEMBER 16 BIT VALUES. - 08FD 1737 CLOSEIT5: - 08FD 13 1738 INC DE ; BUMP TO NEXT ITEM IN TABLE. - 08FE 23 1739 INC HL - 08FF 0D 1740 DEC C ; THERE ARE 16 ENTRIES ONLY. - 0900 C2rCDs08 1741 JP NZ,CLOSEIT1 ; CONTINUE IF MORE TO DO. - 0903 01 EC FF 1742 LD BC,#0x0FFEC ; BACKUP 20 PLACES (EXTENT BYTE). - 0906 09 1743 ADD HL,BC - 0907 EB 1744 EX DE,HL - 0908 09 1745 ADD HL,BC - 0909 1A 1746 LD A,(DE) - 090A BE 1747 CP (HL) ; DIRECTORY'S EXTENT ALREADY GREATER THAN THE - 090B DAr17s09 1748 JP C,CLOSEIT6 ; USERS EXTENT? - 090E 77 1749 LD (HL),A ; NO, UPDATE DIRECTORY EXTENT. - 090F 01 03 00 1750 LD BC,#3 ; AND UPDATE THE RECORD COUNT BYTE IN - 0912 09 1751 ADD HL,BC ; DIRECTORIES FCB. - 0913 EB 1752 EX DE,HL - 0914 09 1753 ADD HL,BC - 0915 7E 1754 LD A,(HL) ; GET FROM USER. - 0916 12 1755 LD (DE),A ; AND PUT IN DIRECTORY. - 0917 1756 CLOSEIT6: - 0917 3E FF 1757 LD A,#0x0FF ; SET 'WAS OPEN AND IS NOW CLOSED' BYTE. - 0919 32rD2s0D 1758 LD (CLOSEFLG),A - 091C C3r10s08 1759 JP UPDATE1 ; UPDATE THE DIRECTORY NOW. - 091F 1760 CLOSEIT7: - 091F 21r45s03 1761 LD HL,#STATUS ; SET RETURN STATUS AND THEN RETURN. - 0922 35 1762 DEC (HL) - 0923 C9 1763 RET - 1764 ; - 1765 ; ROUTINE TO GET THE NEXT EMPTY SPACE IN THE DIRECTORY. IT - 1766 ; WILL THEN BE CLEARED FOR USE. - 1767 ; - 0924 1768 GETEMPTY: - 0924 CDr54s05 1769 CALL CHKWPRT ; MAKE SURE DISK IS NOT WRITE PROTECTED. - 0927 2Ar43s03 1770 LD HL,(PARAMS) ; SAVE CURRENT PARAMETERS (FCB). - 092A E5 1771 PUSH HL - 092B 21rACs0D 1772 LD HL,#EMPTYFCB ; USE SPECIAL ONE FOR EMPTY SPACE. - 092E 22r43s03 1773 LD (PARAMS),HL - 0931 0E 01 1774 LD C,#1 ; SEARCH FOR FIRST EMPTY SPOT IN DIRECTORY. - 0933 CDr18s07 1775 CALL FINDFST ; (* ONLY CHECK FIRST BYTE *) - 0936 CDrF5s05 1776 CALL CKFILPOS ; NONE? - 0939 E1 1777 POP HL - 093A 22r43s03 1778 LD (PARAMS),HL ; RESTORE ORIGINAL FCB ADDRESS. - 093D C8 1779 RET Z ; RETURN IF NO MORE SPACE. - 093E EB 1780 EX DE,HL - 093F 21 0F 00 1781 LD HL,#15 ; POINT TO NUMBER OF RECORDS FOR THIS FILE. - 0942 19 1782 ADD HL,DE - 0943 0E 11 1783 LD C,#17 ; AND CLEAR ALL OF THIS SPACE. - 0945 AF 1784 XOR A - 0946 77 1785 GETMT1: LD (HL),A - 0947 23 1786 INC HL - 0948 0D 1787 DEC C - 0949 C2r46s09 1788 JP NZ,GETMT1 - 094C 21 0D 00 1789 LD HL,#13 ; CLEAR THE 'S1' BYTE ALSO. - 094F 19 1790 ADD HL,DE - 0950 77 1791 LD (HL),A - 0951 CDr8Cs05 1792 CALL CHKNMBR ; KEEP (SCRATCH1) WITHIN BOUNDS. - 0954 CDrFDs07 1793 CALL FCBSET ; WRITE OUT THIS FCB ENTRY TO DIRECTORY. - 0957 C3r78s05 1794 JP SETS2B7 ; SET 'S2' BYTE BIT 7 (UNMODIFIED AT PRESENT). - 1795 ; - 1796 ; ROUTINE TO CLOSE THE CURRENT EXTENT AND OPEN THE NEXT ONE - 1797 ; FOR READING. - 1798 ; - 095A AF 1799 GETNEXT:XOR A - 095B 32rD2s0D 1800 LD (CLOSEFLG),A ; CLEAR CLOSE FLAG. - 095E CDrA2s08 1801 CALL CLOSEIT ; CLOSE THIS EXTENT. - 0961 CDrF5s05 1802 CALL CKFILPOS - 0964 C8 1803 RET Z ; NOT THERE??? - 0965 2Ar43s03 1804 LD HL,(PARAMS) ; GET EXTENT BYTE. - 0968 01 0C 00 1805 LD BC,#12 - 096B 09 1806 ADD HL,BC - 096C 7E 1807 LD A,(HL) ; AND INCREMENT IT. - 096D 3C 1808 INC A - 096E E6 1F 1809 AND #0x1F ; KEEP WITHIN RANGE 0-31. - 0970 77 1810 LD (HL),A - 0971 CAr83s09 1811 JP Z,GTNEXT1 ; OVERFLOW? - 0974 47 1812 LD B,A ; MASK EXTENT BYTE. - 0975 3ArC5s0D 1813 LD A,(EXTMASK) - 0978 A0 1814 AND B - 0979 21rD2s0D 1815 LD HL,#CLOSEFLG ; CHECK CLOSE FLAG (0FFH IS OK). - 097C A6 1816 AND (HL) - 097D CAr8Es09 1817 JP Z,GTNEXT2 ; IF ZERO, WE MUST READ IN NEXT EXTENT. - 0980 C3rACs09 1818 JP GTNEXT3 ; ELSE, IT IS ALREADY IN MEMORY. - 0983 01 02 00 1819 GTNEXT1:LD BC,#2 ; POINT TO THE 'S2' BYTE. - 0986 09 1820 ADD HL,BC - 0987 34 1821 INC (HL) ; AND BUMP IT. - 0988 7E 1822 LD A,(HL) ; TOO MANY EXTENTS? - 0989 E6 0F 1823 AND #0x0F - 098B CArB6s09 1824 JP Z,GTNEXT5 ; YES, SET ERROR CODE. - 1825 ; - 1826 ; GET HERE TO OPEN THE NEXT EXTENT. - 1827 ; - 098E 0E 0F 1828 GTNEXT2:LD C,#15 ; SET TO CHECK FIRST 15 BYTES OF FCB. - 0990 CDr18s07 1829 CALL FINDFST ; FIND THE FIRST ONE. - 0993 CDrF5s05 1830 CALL CKFILPOS ; NONE AVAILABLE? - 0996 C2rACs09 1831 JP NZ,GTNEXT3 - 0999 3ArD3s0D 1832 LD A,(R.DWRTFLG) ; NO EXTENT PRESENT. CAN WE OPEN AN EMPTY ONE? - 099C 3C 1833 INC A ; 0FFH MEANS READING (SO NOT POSSIBLE). - 099D CArB6s09 1834 JP Z,GTNEXT5 ; OR AN ERROR. - 09A0 CDr24s09 1835 CALL GETEMPTY ; WE ARE WRITING, GET AN EMPTY ENTRY. - 09A3 CDrF5s05 1836 CALL CKFILPOS ; NONE? - 09A6 CArB6s09 1837 JP Z,GTNEXT5 ; ERROR IF TRUE. - 09A9 C3rAFs09 1838 JP GTNEXT4 ; ELSE WE ARE ALMOST DONE. - 09AC CDr5As08 1839 GTNEXT3:CALL OPENIT1 ; OPEN THIS EXTENT. - 09AF CDrBBs04 1840 GTNEXT4:CALL STRDATA ; MOVE IN UPDATED DATA (REC #, EXTENT #, ETC.) - 09B2 AF 1841 XOR A ; CLEAR STATUS AND RETURN. - 09B3 C3r01s03 1842 JP SETSTAT - 1843 ; - 1844 ; ERROR IN EXTENDING THE FILE. TOO MANY EXTENTS WERE NEEDED - 1845 ; OR NOT ENOUGH SPACE ON THE DISK. - 1846 ; - 09B6 CDr05s03 1847 GTNEXT5:CALL IOERR1 ; SET ERROR CODE, CLEAR BIT 7 OF 'S2' - 09B9 C3r78s05 1848 JP SETS2B7 ; SO THIS IS NOT WRITTEN ON A CLOSE. - 1849 ; - 1850 ; READ A S.EQUENTIAL FILE. - 1851 ; - 09BC 3E 01 1852 RDSEQ: LD A,#1 ; SET S.EQUENTIAL ACCESS MODE. - 09BE 32rD5s0D 1853 LD (MODE),A - 09C1 3E FF 1854 RDSEQ1: LD A,#0x0FF ; DON'T ALLOW READING UNWRITTEN SPACE. - 09C3 32rD3s0D 1855 LD (R.DWRTFLG),A - 09C6 CDrBBs04 1856 CALL STRDATA ; PUT REC# AND EXT# INTO FCB. - 09C9 3ArE3s0D 1857 LD A,(SAVNREC) ; GET NEXT RECORD TO READ. - 09CC 21rE1s0D 1858 LD HL,#SAVNXT ; GET NUMBER OF RECORDS IN EXTENT. - 09CF BE 1859 CP (HL) ; WITHIN THIS EXTENT? - 09D0 DArE6s09 1860 JP C,RDSEQ2 - 09D3 FE 80 1861 CP #128 ; NO. IS THIS EXTENT FULLY USED? - 09D5 C2rFBs09 1862 JP NZ,RDSEQ3 ; NO. END-OF-FILE. - 09D8 CDr5As09 1863 CALL GETNEXT ; YES, OPEN THE NEXT ONE. - 09DB AF 1864 XOR A ; RESET NEXT RECORD TO READ. - 09DC 32rE3s0D 1865 LD (SAVNREC),A - 09DF 3Ar45s03 1866 LD A,(STATUS) ; CHECK ON OPEN, SUCCESSFUL? - 09E2 B7 1867 OR A - 09E3 C2rFBs09 1868 JP NZ,RDSEQ3 ; NO, ERROR. - 09E6 CDr77s04 1869 RDSEQ2: CALL COMBLK ; OK. COMPUTE BLOCK NUMBER TO READ. - 09E9 CDr84s04 1870 CALL CHKBLK ; CHECK IT. WITHIN BOUNDS? - 09EC CArFBs09 1871 JP Z,RDSEQ3 ; NO, ERROR. - 09EF CDr8As04 1872 CALL LOGICAL ; CONVERT (BLKNMBR) TO LOGICAL SECTOR (128 BYTE). - 09F2 CDrD1s03 1873 CALL TRKSEC1 ; SET THE TRACK AND SECTOR FOR THIS BLOCK #. - 09F5 CDrB2s03 1874 CALL DOREAD ; AND READ IT. - 09F8 C3rD2s04 1875 JP SETNREC ; AND SET THE NEXT RECORD TO BE ACCESSED. - 1876 ; - 1877 ; READ ERROR OCCURED. SET STATUS AND RETURN. - 1878 ; - 09FB C3r05s03 1879 RDSEQ3: JP IOERR1 - 1880 ; - 1881 ; WRITE THE NEXT S.EQUENTIAL RECORD. - 1882 ; - 09FE 3E 01 1883 WTSEQ: LD A,#1 ; SET S.EQUENTIAL ACCESS MODE. - 0A00 32rD5s0D 1884 LD (MODE),A - 0A03 3E 00 1885 WTSEQ1: LD A,#0 ; ALLOW AN ADDITION EMPTY EXTENT TO BE OPENED. - 0A05 32rD3s0D 1886 LD (R.DWRTFLG),A - 0A08 CDr54s05 1887 CALL CHKWPRT ; CHECK WRITE PROTECT STATUS. - 0A0B 2Ar43s03 1888 LD HL,(PARAMS) - 0A0E CDr47s05 1889 CALL CKROF1 ; CHECK FOR READ ONLY FILE, (HL) ALREADY SET TO FCB. - 0A11 CDrBBs04 1890 CALL STRDATA ; PUT UPDATED DATA INTO FCB. - 0A14 3ArE3s0D 1891 LD A,(SAVNREC) ; GET RECORD NUMBER TO WRITE. - 0A17 FE 80 1892 CP #128 ; WITHIN RANGE? - 0A19 D2r05s03 1893 JP NC,IOERR1 ; NO, ERROR(?). - 0A1C CDr77s04 1894 CALL COMBLK ; COMPUTE BLOCK NUMBER. - 0A1F CDr84s04 1895 CALL CHKBLK ; CHECK NUMBER. - 0A22 0E 00 1896 LD C,#0 ; IS THERE ONE TO WRITE TO? - 0A24 C2r6Es0A 1897 JP NZ,WTSEQ6 ; YES, GO DO IT. - 0A27 CDr3Es04 1898 CALL GETBLOCK ; GET NEXT BLOCK NUMBER WITHIN FCB TO USE. - 0A2A 32rD7s0D 1899 LD (RELBLOCK),A ; AND SAVE. - 0A2D 01 00 00 1900 LD BC,#0 ; START LOOKING FOR SPACE FROM THE START - 0A30 B7 1901 OR A ; IF NONE ALLOCATED AS YET. - 0A31 CAr3Bs0A 1902 JP Z,WTSEQ2 - 0A34 4F 1903 LD C,A ; EXTRACT PREVIOUS BLOCK NUMBER FROM FCB - 0A35 0B 1904 DEC BC ; SO WE CAN BE CLOSEST TO IT. - 0A36 CDr5Es04 1905 CALL EXTBLK - 0A39 44 1906 LD B,H - 0A3A 4D 1907 LD C,L - 0A3B CDrBEs07 1908 WTSEQ2: CALL FNDSPACE ; FIND THE NEXT EMPTY BLOCK NEAREST NUMBER (BC). - 0A3E 7D 1909 LD A,L ; CHECK FOR A ZERO NUMBER. - 0A3F B4 1910 OR H - 0A40 C2r48s0A 1911 JP NZ,WTSEQ3 - 0A43 3E 02 1912 LD A,#2 ; NO MORE SPACE? - 0A45 C3r01s03 1913 JP SETSTAT - 0A48 22rE5s0D 1914 WTSEQ3: LD (BLKNMBR),HL ; SAVE BLOCK NUMBER TO ACCESS. - 0A4B EB 1915 EX DE,HL ; PUT BLOCK NUMBER INTO (DE). - 0A4C 2Ar43s03 1916 LD HL,(PARAMS) ; NOW WE MUST UPDATE THE FCB FOR THIS - 0A4F 01 10 00 1917 LD BC,#16 ; NEWLY ALLOCATED BLOCK. - 0A52 09 1918 ADD HL,BC - 0A53 3ArDDs0D 1919 LD A,(BIGDISK) ; 8 OR 16 BIT BLOCK NUMBERS? - 0A56 B7 1920 OR A - 0A57 3ArD7s0D 1921 LD A,(RELBLOCK) ; (* UPDATE THIS ENTRY *) - 0A5A CAr64s0A 1922 JP Z,WTSEQ4 ; ZERO MEANS 16 BIT ONES. - 0A5D CDr64s05 1923 CALL ADDA2HL ; (HL)=(HL)+(A) - 0A60 73 1924 LD (HL),E ; STORE NEW BLOCK NUMBER. - 0A61 C3r6Cs0A 1925 JP WTSEQ5 - 0A64 4F 1926 WTSEQ4: LD C,A ; COMPUTE SPOT IN THIS 16 BIT TABLE. - 0A65 06 00 1927 LD B,#0 - 0A67 09 1928 ADD HL,BC - 0A68 09 1929 ADD HL,BC - 0A69 73 1930 LD (HL),E ; STUFF BLOCK NUMBER (DE) THERE. - 0A6A 23 1931 INC HL - 0A6B 72 1932 LD (HL),D - 0A6C 0E 02 1933 WTSEQ5: LD C,#2 ; SET (C) TO INDICATE WRITING TO UN-USED DISK SPACE. - 0A6E 3Ar45s03 1934 WTSEQ6: LD A,(STATUS) ; ARE WE OK SO FAR? - 0A71 B7 1935 OR A - 0A72 C0 1936 RET NZ - 0A73 C5 1937 PUSH BC ; YES, SAVE WRITE FLAG FOR BIOS (REGISTER C). - 0A74 CDr8As04 1938 CALL LOGICAL ; CONVERT (BLKNMBR) OVER TO LOICAL SECTORS. - 0A77 3ArD5s0D 1939 LD A,(MODE) ; GET ACCESS MODE FLAG (1=S.EQUENTIAL, - 0A7A 3D 1940 DEC A ; 0=RANDOM, 2=SPECIAL?). - 0A7B 3D 1941 DEC A - 0A7C C2rBBs0A 1942 JP NZ,WTSEQ9 - 1943 ; - 1944 ; SPECIAL RANDOM I/O FROM FUNCTION #40. MAYBE FOR M/PM, BUT THE - 1945 ; CURRENT BLOCK, IF IT HAS NOT BEEN WRITTEN TO, WILL BE ZEROED - 1946 ; OUT AND THEN WRITTEN (REASON?). - 1947 ; - 0A7F C1 1948 POP BC - 0A80 C5 1949 PUSH BC - 0A81 79 1950 LD A,C ; GET WRITE STATUS FLAG (2=WRITING UNUSED SPACE). - 0A82 3D 1951 DEC A - 0A83 3D 1952 DEC A - 0A84 C2rBBs0A 1953 JP NZ,WTSEQ9 - 0A87 E5 1954 PUSH HL - 0A88 2ArB9s0D 1955 LD HL,(DIRBUF) ; ZERO OUT THE DIRECTORY BUFFER. - 0A8B 57 1956 LD D,A ; NOTE THAT (A) IS ZERO HERE. - 0A8C 77 1957 WTSEQ7: LD (HL),A - 0A8D 23 1958 INC HL - 0A8E 14 1959 INC D ; DO 128 BYTES. - 0A8F F2r8Cs0A 1960 JP P,WTSEQ7 - 0A92 CDrE0s05 1961 CALL DIRDMA ; TELL THE BIOS THE DMA ADDRESS FOR DIRECTORY ACCESS. - 0A95 2ArE7s0D 1962 LD HL,(LOGSECT) ; GET SECTOR THAT STARTS CURRENT BLOCK. - 0A98 0E 02 1963 LD C,#2 ; SET 'WRITING TO UNUSED SPACE' FLAG. - 0A9A 22rE5s0D 1964 WTSEQ8: LD (BLKNMBR),HL ; SAVE SECTOR TO WRITE. - 0A9D C5 1965 PUSH BC - 0A9E CDrD1s03 1966 CALL TRKSEC1 ; DETERMINE ITS TRACK AND SECTOR NUMBERS. - 0AA1 C1 1967 POP BC - 0AA2 CDrB8s03 1968 CALL DOWRITE ; NOW WRITE OUT 128 BYTES OF ZEROS. - 0AA5 2ArE5s0D 1969 LD HL,(BLKNMBR) ; GET SECTOR NUMBER. - 0AA8 0E 00 1970 LD C,#0 ; SET NORMAL WRITE FLAG. - 0AAA 3ArC4s0D 1971 LD A,(BLKMASK) ; DETERMINE IF WE HAVE WRITTEN THE ENTIRE - 0AAD 47 1972 LD B,A ; PHYSICAL BLOCK. - 0AAE A5 1973 AND L - 0AAF B8 1974 CP B - 0AB0 23 1975 INC HL ; PREPARE FOR THE NEXT ONE. - 0AB1 C2r9As0A 1976 JP NZ,WTSEQ8 ; CONTINUE UNTIL (BLKMASK+1) SECTORS WRITTEN. - 0AB4 E1 1977 POP HL ; RESET NEXT SECTOR NUMBER. - 0AB5 22rE5s0D 1978 LD (BLKNMBR),HL - 0AB8 CDrDAs05 1979 CALL DEFDMA ; AND RESET DMA ADDRESS. - 1980 ; - 1981 ; NORMAL DISK WRITE. SET THE DESIRED TRACK AND SECTOR THEN - 1982 ; DO THE ACTUAL WRITE. - 1983 ; - 0ABB CDrD1s03 1984 WTSEQ9: CALL TRKSEC1 ; DETERMINE TRACK AND SECTOR FOR THIS WRITE. - 0ABE C1 1985 POP BC ; GET WRITE STATUS FLAG. - 0ABF C5 1986 PUSH BC - 0AC0 CDrB8s03 1987 CALL DOWRITE ; AND WRITE THIS OUT. - 0AC3 C1 1988 POP BC - 0AC4 3ArE3s0D 1989 LD A,(SAVNREC) ; GET NUMBER OF RECORDS IN FILE. - 0AC7 21rE1s0D 1990 LD HL,#SAVNXT ; GET LAST RECORD WRITTEN. - 0ACA BE 1991 CP (HL) - 0ACB DArD2s0A 1992 JP C,WTSEQ10 - 0ACE 77 1993 LD (HL),A ; WE HAVE TO UPDATE RECORD COUNT. - 0ACF 34 1994 INC (HL) - 0AD0 0E 02 1995 LD C,#2 - 1996 ; - 1997 ;* THIS AREA HAS BEEN PATCHED TO CORRECT DISK UPDATE PROBLEM - 1998 ;* WHEN USING BLOCKING AND DE-BLOCKING IN THE BIOS. - 1999 ; - 0AD2 00 2000 WTSEQ10:NOP ; WAS 'DCR C' - 0AD3 00 2001 NOP ; WAS 'DCR C' - 0AD4 21 00 00 2002 LD HL,#0 ; WAS 'JNZ WTSEQ99' - 2003 ; - 2004 ; * END OF PATCH. - 2005 ; - 0AD7 F5 2006 PUSH AF - 0AD8 CDr69s05 2007 CALL GETS2 ; SET 'EXTENT WRITTEN TO' FLAG. - 0ADB E6 7F 2008 AND #0x7F ; (* CLEAR BIT 7 *) - 0ADD 77 2009 LD (HL),A - 0ADE F1 2010 POP AF ; GET RECORD COUNT FOR THIS EXTENT. - 0ADF FE 7F 2011 WTSEQ99:CP #127 ; IS IT FULL? - 0AE1 C2r00s0B 2012 JP NZ,WTSEQ12 - 0AE4 3ArD5s0D 2013 LD A,(MODE) ; YES, ARE WE IN S.EQUENTIAL MODE? - 0AE7 FE 01 2014 CP #1 - 0AE9 C2r00s0B 2015 JP NZ,WTSEQ12 - 0AEC CDrD2s04 2016 CALL SETNREC ; YES, SET NEXT RECORD NUMBER. - 0AEF CDr5As09 2017 CALL GETNEXT ; AND GET NEXT EMPTY SPACE IN DIRECTORY. - 0AF2 21r45s03 2018 LD HL,#STATUS ; OK? - 0AF5 7E 2019 LD A,(HL) - 0AF6 B7 2020 OR A - 0AF7 C2rFEs0A 2021 JP NZ,WTSEQ11 - 0AFA 3D 2022 DEC A ; YES, SET RECORD COUNT TO -1. - 0AFB 32rE3s0D 2023 LD (SAVNREC),A - 0AFE 36 00 2024 WTSEQ11:LD (HL),#0 ; CLEAR STATUS. - 0B00 C3rD2s04 2025 WTSEQ12:JP SETNREC ; SET NEXT RECORD TO ACCESS. - 2026 ; - 2027 ; FOR RANDOM I/O, SET THE FCB FOR THE DESIRED RECORD NUMBER - 2028 ; BASED ON THE 'R0,R1,R2' BYTES. THESE BYTES IN THE FCB ARE - 2029 ; USED AS FOLLOWS: - 2030 ; - 2031 ; FCB+35 FCB+34 FCB+33 - 2032 ; | 'R-2' | 'R-1' | 'R-0' | - 2033 ; |7 0 | 7 0 | 7 0| - 2034 ; |0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0| - 2035 ; | OVERFLOW | | EXTRA | EXTENT | RECORD # | - 2036 ; | ______________| |_EXTENT|__NUMBER___|_____________| - 2037 ; ALSO 'S2' - 2038 ; - 2039 ; ON ENTRY, REGISTER (C) CONTAINS 0FFH IF THIS IS A READ - 2040 ; AND THUS WE CAN NOT ACCESS UNWRITTEN DISK SPACE. OTHERWISE, - 2041 ; ANOTHER EXTENT WILL BE OPENED (FOR WRITING) IF R.EQUIRED. - 2042 ; - 0B03 2043 POSITION: - 0B03 AF 2044 XOR A ; SET RANDOM I/O FLAG. - 0B04 32rD5s0D 2045 LD (MODE),A - 2046 ; - 2047 ; SPECIAL ENTRY (FUNCTION #40). M/PM ? - 2048 ; - 0B07 C5 2049 POSITN1:PUSH BC ; SAVE READ/WRITE FLAG. - 0B08 2Ar43s03 2050 LD HL,(PARAMS) ; GET ADDRESS OF FCB. - 0B0B EB 2051 EX DE,HL - 0B0C 21 21 00 2052 LD HL,#33 ; NOW GET BYTE 'R0'. - 0B0F 19 2053 ADD HL,DE - 0B10 7E 2054 LD A,(HL) - 0B11 E6 7F 2055 AND #0x7F ; KEEP BITS 0-6 FOR THE RECORD NUMBER TO ACCESS. - 0B13 F5 2056 PUSH AF - 0B14 7E 2057 LD A,(HL) ; NOW GET BIT 7 OF 'R0' AND BITS 0-3 OF 'R1'. - 0B15 17 2058 RLA - 0B16 23 2059 INC HL - 0B17 7E 2060 LD A,(HL) - 0B18 17 2061 RLA - 0B19 E6 1F 2062 AND #0x1F ; AND SAVE THIS IN BITS 0-4 OF (C). - 0B1B 4F 2063 LD C,A ; THIS IS THE EXTENT BYTE. - 0B1C 7E 2064 LD A,(HL) ; NOW GET THE EXTRA EXTENT BYTE. - 0B1D 1F 2065 RRA - 0B1E 1F 2066 RRA - 0B1F 1F 2067 RRA - 0B20 1F 2068 RRA - 0B21 E6 0F 2069 AND #0x0F - 0B23 47 2070 LD B,A ; AND SAVE IT IN (B). - 0B24 F1 2071 POP AF ; GET RECORD NUMBER BACK TO (A). - 0B25 23 2072 INC HL ; CHECK OVERFLOW BYTE 'R2'. - 0B26 6E 2073 LD L,(HL) - 0B27 2C 2074 INC L - 0B28 2D 2075 DEC L - 0B29 2E 06 2076 LD L,#6 ; PREPARE FOR ERROR. - 0B2B C2r8Bs0B 2077 JP NZ,POSITN5 ; OUT OF DISK SPACE ERROR. - 0B2E 21 20 00 2078 LD HL,#32 ; STORE RECORD NUMBER INTO FCB. - 0B31 19 2079 ADD HL,DE - 0B32 77 2080 LD (HL),A - 0B33 21 0C 00 2081 LD HL,#12 ; AND NOW CHECK THE EXTENT BYTE. - 0B36 19 2082 ADD HL,DE - 0B37 79 2083 LD A,C - 0B38 96 2084 SUB (HL) ; SAME EXTENT AS BEFORE? - 0B39 C2r47s0B 2085 JP NZ,POSITN2 - 0B3C 21 0E 00 2086 LD HL,#14 ; YES, CHECK EXTRA EXTENT BYTE 'S2' ALSO. - 0B3F 19 2087 ADD HL,DE - 0B40 78 2088 LD A,B - 0B41 96 2089 SUB (HL) - 0B42 E6 7F 2090 AND #0x7F - 0B44 CAr7Fs0B 2091 JP Z,POSITN3 ; SAME, WE ARE ALMOST DONE THEN. - 2092 ; - 2093 ; GET HERE WHEN ANOTHER EXTENT IS R.EQUIRED. - 2094 ; - 0B47 C5 2095 POSITN2:PUSH BC - 0B48 D5 2096 PUSH DE - 0B49 CDrA2s08 2097 CALL CLOSEIT ; CLOSE CURRENT EXTENT. - 0B4C D1 2098 POP DE - 0B4D C1 2099 POP BC - 0B4E 2E 03 2100 LD L,#3 ; PREPARE FOR ERROR. - 0B50 3Ar45s03 2101 LD A,(STATUS) - 0B53 3C 2102 INC A - 0B54 CAr84s0B 2103 JP Z,POSITN4 ; CLOSE ERROR. - 0B57 21 0C 00 2104 LD HL,#12 ; PUT DESIRED EXTENT INTO FCB NOW. - 0B5A 19 2105 ADD HL,DE - 0B5B 71 2106 LD (HL),C - 0B5C 21 0E 00 2107 LD HL,#14 ; AND STORE EXTRA EXTENT BYTE 'S2'. - 0B5F 19 2108 ADD HL,DE - 0B60 70 2109 LD (HL),B - 0B61 CDr51s08 2110 CALL OPENIT ; TRY AND GET THIS EXTENT. - 0B64 3Ar45s03 2111 LD A,(STATUS) ; WAS IT THERE? - 0B67 3C 2112 INC A - 0B68 C2r7Fs0B 2113 JP NZ,POSITN3 - 0B6B C1 2114 POP BC ; NO. CAN WE CREATE A NEW ONE (WRITING?). - 0B6C C5 2115 PUSH BC - 0B6D 2E 04 2116 LD L,#4 ; PREPARE FOR ERROR. - 0B6F 0C 2117 INC C - 0B70 CAr84s0B 2118 JP Z,POSITN4 ; NOPE, READING UNWRITTEN SPACE ERROR. - 0B73 CDr24s09 2119 CALL GETEMPTY ; YES WE CAN, TRY TO FIND SPACE. - 0B76 2E 05 2120 LD L,#5 ; PREPARE FOR ERROR. - 0B78 3Ar45s03 2121 LD A,(STATUS) - 0B7B 3C 2122 INC A - 0B7C CAr84s0B 2123 JP Z,POSITN4 ; OUT OF SPACE? - 2124 ; - 2125 ; NORMAL RETURN LOCATION. CLEAR ERROR CODE AND RETURN. - 2126 ; - 0B7F C1 2127 POSITN3:POP BC ; RESTORE STACK. - 0B80 AF 2128 XOR A ; AND CLEAR ERROR CODE BYTE. - 0B81 C3r01s03 2129 JP SETSTAT - 2130 ; - 2131 ; ERROR. SET THE 'S2' BYTE TO INDICATE THIS (WHY?). - 2132 ; - 0B84 E5 2133 POSITN4:PUSH HL - 0B85 CDr69s05 2134 CALL GETS2 - 0B88 36 C0 2135 LD (HL),#0x0C0 - 0B8A E1 2136 POP HL - 2137 ; - 2138 ; RETURN WITH ERROR CODE (PRESENTLY IN L). - 2139 ; - 0B8B C1 2140 POSITN5:POP BC - 0B8C 7D 2141 LD A,L ; GET ERROR CODE. - 0B8D 32r45s03 2142 LD (STATUS),A - 0B90 C3r78s05 2143 JP SETS2B7 - 2144 ; - 2145 ; READ A RANDOM RECORD. - 2146 ; - 0B93 0E FF 2147 READRAN:LD C,#0x0FF ; SET 'READ' STATUS. - 0B95 CDr03s0B 2148 CALL POSITION ; POSITION THE FILE TO PROPER RECORD. - 0B98 CCrC1s09 2149 CALL Z,RDSEQ1 ; AND READ IT AS USUAL (IF NO ERRORS). - 0B9B C9 2150 RET - 2151 ; - 2152 ; WRITE TO A RANDOM RECORD. - 2153 ; - 0B9C 2154 WRITERAN: - 0B9C 0E 00 2155 LD C,#0 ; SET 'WRITING' FLAG. - 0B9E CDr03s0B 2156 CALL POSITION ; POSITION THE FILE TO PROPER RECORD. - 0BA1 CCr03s0A 2157 CALL Z,WTSEQ1 ; AND WRITE AS USUAL (IF NO ERRORS). - 0BA4 C9 2158 RET - 2159 ; - 2160 ; COMPUTE THE RANDOM RECORD NUMBER. ENTER WITH (HL) POINTING - 2161 ; TO A FCB AN (DE) CONTAINS A RELATIVE LOCATION OF A RECORD - 2162 ; NUMBER. ON EXIT, (C) CONTAINS THE 'R0' BYTE, (B) THE 'R1' - 2163 ; BYTE, AND (A) THE 'R2' BYTE. - 2164 ; - 2165 ; ON RETURN, THE ZERO FLAG IS SET IF THE RECORD IS WITHIN - 2166 ; BOUNDS. OTHERWISE, AN OVERFLOW OCCURED. - 2167 ; - 0BA5 2168 COMPRAND: - 0BA5 EB 2169 EX DE,HL ; SAVE FCB POINTER IN (DE). - 0BA6 19 2170 ADD HL,DE ; COMPUTE RELATIVE POSITION OF RECORD #. - 0BA7 4E 2171 LD C,(HL) ; GET RECORD NUMBER INTO (BC). - 0BA8 06 00 2172 LD B,#0 - 0BAA 21 0C 00 2173 LD HL,#12 ; NOW GET EXTENT. - 0BAD 19 2174 ADD HL,DE - 0BAE 7E 2175 LD A,(HL) ; COMPUTE (BC)=(RECORD #)+(EXTENT)*128. - 0BAF 0F 2176 RRCA ; MOVE LOWER BIT INTO BIT 7. - 0BB0 E6 80 2177 AND #0x80 ; AND IGNORE ALL OTHER BITS. - 0BB2 81 2178 ADD A,C ; ADD TO OUR RECORD NUMBER. - 0BB3 4F 2179 LD C,A - 0BB4 3E 00 2180 LD A,#0 ; TAKE CARE OF ANY CARRY. - 0BB6 88 2181 ADC A,B - 0BB7 47 2182 LD B,A - 0BB8 7E 2183 LD A,(HL) ; NOW GET THE UPPER BITS OF EXTENT INTO - 0BB9 0F 2184 RRCA ; BIT POSITIONS 0-3. - 0BBA E6 0F 2185 AND #0x0F ; AND IGNORE ALL OTHERS. - 0BBC 80 2186 ADD A,B ; ADD THIS IN TO 'R1' BYTE. - 0BBD 47 2187 LD B,A - 0BBE 21 0E 00 2188 LD HL,#14 ; GET THE 'S2' BYTE (EXTRA EXTENT). - 0BC1 19 2189 ADD HL,DE - 0BC2 7E 2190 LD A,(HL) - 0BC3 87 2191 ADD A,A ; AND SHIFT IT LEFT 4 BITS (BITS 4-7). - 0BC4 87 2192 ADD A,A - 0BC5 87 2193 ADD A,A - 0BC6 87 2194 ADD A,A - 0BC7 F5 2195 PUSH AF ; SAVE CARRY FLAG (BIT 0 OF FLAG BYTE). - 0BC8 80 2196 ADD A,B ; NOW ADD EXTRA EXTENT INTO 'R1'. - 0BC9 47 2197 LD B,A - 0BCA F5 2198 PUSH AF ; AND SAVE CARRY (OVERFLOW BYTE 'R2'). - 0BCB E1 2199 POP HL ; BIT 0 OF (L) IS THE OVERFLOW INDICATOR. - 0BCC 7D 2200 LD A,L - 0BCD E1 2201 POP HL ; AND SAME FOR FIRST CARRY FLAG. - 0BCE B5 2202 OR L ; EITHER ONE OF THESE SET? - 0BCF E6 01 2203 AND #1 ; ONLY CHECK THE CARRY FLAGS. - 0BD1 C9 2204 RET - 2205 ; - 2206 ; ROUTINE TO SETUP THE FCB (BYTES 'R0', 'R1', 'R2') TO - 2207 ; REFLECT THE LAST RECORD USED FOR A RANDOM (OR OTHER) FILE. - 2208 ; THIS READS THE DIRECTORY AND LOOKS AT ALL EXTENTS COMPUTING - 2209 ; THE LARGERST RECORD NUMBER FOR EACH AND KEEPING THE MAXIMUM - 2210 ; VALUE ONLY. THEN 'R0', 'R1', AND 'R2' WILL REFLECT THIS - 2211 ; MAXIMUM RECORD NUMBER. THIS IS USED TO COMPUTE THE SPACE USED - 2212 ; BY A RANDOM FILE. - 2213 ; - 0BD2 0E 0C 2214 RANSIZE:LD C,#12 ; LOOK THRU DIRECTORY FOR FIRST ENTRY WITH - 0BD4 CDr18s07 2215 CALL FINDFST ; THIS NAME. - 0BD7 2Ar43s03 2216 LD HL,(PARAMS) ; ZERO OUT THE 'R0, R1, R2' BYTES. - 0BDA 11 21 00 2217 LD DE,#33 - 0BDD 19 2218 ADD HL,DE - 0BDE E5 2219 PUSH HL - 0BDF 72 2220 LD (HL),D ; NOTE THAT (D)=0. - 0BE0 23 2221 INC HL - 0BE1 72 2222 LD (HL),D - 0BE2 23 2223 INC HL - 0BE3 72 2224 LD (HL),D - 0BE4 CDrF5s05 2225 RANSIZ1:CALL CKFILPOS ; IS THERE AN EXTENT TO PROCESS? - 0BE7 CAr0Cs0C 2226 JP Z,RANSIZ3 ; NO, WE ARE DONE. - 0BEA CDr5Es05 2227 CALL FCB2HL ; SET (HL) POINTING TO PROPER FCB IN DIR. - 0BED 11 0F 00 2228 LD DE,#15 ; POINT TO LAST RECORD IN EXTENT. - 0BF0 CDrA5s0B 2229 CALL COMPRAND ; AND COMPUTE RANDOM PARAMETERS. - 0BF3 E1 2230 POP HL - 0BF4 E5 2231 PUSH HL ; NOW CHECK THESE VALUES AGAINST THOSE - 0BF5 5F 2232 LD E,A ; ALREADY IN FCB. - 0BF6 79 2233 LD A,C ; THE CARRY FLAG WILL BE SET IF THOSE - 0BF7 96 2234 SUB (HL) ; IN THE FCB REPRESENT A LARGER SIZE THAN - 0BF8 23 2235 INC HL ; THIS EXTENT DOES. - 0BF9 78 2236 LD A,B - 0BFA 9E 2237 SBC A,(HL) - 0BFB 23 2238 INC HL - 0BFC 7B 2239 LD A,E - 0BFD 9E 2240 SBC A,(HL) - 0BFE DAr06s0C 2241 JP C,RANSIZ2 - 0C01 73 2242 LD (HL),E ; WE FOUND A LARGER (IN SIZE) EXTENT. - 0C02 2B 2243 DEC HL ; STUFF THESE VALUES INTO FCB. - 0C03 70 2244 LD (HL),B - 0C04 2B 2245 DEC HL - 0C05 71 2246 LD (HL),C - 0C06 CDr2Ds07 2247 RANSIZ2:CALL FINDNXT ; NOW GET THE NEXT EXTENT. - 0C09 C3rE4s0B 2248 JP RANSIZ1 ; CONTINUE TIL ALL DONE. - 0C0C E1 2249 RANSIZ3:POP HL ; WE ARE DONE, RESTORE THE STACK AND - 0C0D C9 2250 RET ; RETURN. - 2251 ; - 2252 ; FUNCTION TO RETURN THE RANDOM RECORD POSITION OF A GIVEN - 2253 ; FILE WHICH HAS BEEN READ IN S.EQUENTIAL MODE UP TO NOW. - 2254 ; - 0C0E 2Ar43s03 2255 SETRAN: LD HL,(PARAMS) ; POINT TO FCB. - 0C11 11 20 00 2256 LD DE,#32 ; AND TO LAST USED RECORD. - 0C14 CDrA5s0B 2257 CALL COMPRAND ; COMPUTE RANDOM POSITION. - 0C17 21 21 00 2258 LD HL,#33 ; NOW STUFF THESE VALUES INTO FCB. - 0C1A 19 2259 ADD HL,DE - 0C1B 71 2260 LD (HL),C ; MOVE 'R0'. - 0C1C 23 2261 INC HL - 0C1D 70 2262 LD (HL),B ; AND 'R1'. - 0C1E 23 2263 INC HL - 0C1F 77 2264 LD (HL),A ; AND LASTLY 'R2'. - 0C20 C9 2265 RET - 2266 ; - 2267 ; THIS ROUTINE SELECT THE DRIVE SPECIFIED IN (ACTIVE) AND - 2268 ; UPDATE THE LOGIN VECTOR AND BITMAP TABLE IF THIS DRIVE WAS - 2269 ; NOT ALREADY ACTIVE. - 2270 ; - 0C21 2271 LOGINDRV: - 0C21 2ArAFs0D 2272 LD HL,(LOGIN) ; GET THE LOGIN VECTOR. - 0C24 3Ar42s03 2273 LD A,(ACTIVE) ; GET THE DEFAULT DRIVE. - 0C27 4F 2274 LD C,A - 0C28 CDrEAs04 2275 CALL SHIFTR ; POSITION ACTIVE BIT FOR THIS DRIVE - 0C2B E5 2276 PUSH HL ; INTO BIT 0. - 0C2C EB 2277 EX DE,HL - 0C2D CDr59s03 2278 CALL SELECT ; SELECT THIS DRIVE. - 0C30 E1 2279 POP HL - 0C31 CCr47s03 2280 CALL Z,SLCTERR ; VALID DRIVE? - 0C34 7D 2281 LD A,L ; IS THIS A NEWLY ACTIVATED DRIVE? - 0C35 1F 2282 RRA - 0C36 D8 2283 RET C - 0C37 2ArAFs0D 2284 LD HL,(LOGIN) ; YES, UPDATE THE LOGIN VECTOR. - 0C3A 4D 2285 LD C,L - 0C3B 44 2286 LD B,H - 0C3C CDr0Bs05 2287 CALL SETBIT - 0C3F 22rAFs0D 2288 LD (LOGIN),HL ; AND SAVE. - 0C42 C3rA3s06 2289 JP BITMAP ; NOW UPDATE THE BITMAP. - 2290 ; - 2291 ; FUNCTION TO SET THE ACTIVE DISK NUMBER. - 2292 ; - 0C45 3ArD6s0D 2293 SETDSK: LD A,(EPARAM) ; GET PARAMETER PASSED AND SEE IF THIS - 0C48 21r42s03 2294 LD HL,#ACTIVE ; REPRESENTS A CHANGE IN DRIVES. - 0C4B BE 2295 CP (HL) - 0C4C C8 2296 RET Z - 0C4D 77 2297 LD (HL),A ; YES IT DOES, LOG IT IN. - 0C4E C3r21s0C 2298 JP LOGINDRV - 2299 ; - 2300 ; THIS IS THE 'AUTO DISK SELECT' ROUTINE. THE FIRSST BYTE - 2301 ; OF THE FCB IS EXAMINED FOR A DRIVE SPECIFICATION. IF NON - 2302 ; ZERO THEN THE DRIVE WILL BE SELECTED AND LOGED IN. - 2303 ; - 0C51 3E FF 2304 AUTOSEL:LD A,#0x0FF ; SAY 'AUTO-SELECT ACTIVATED'. - 0C53 32rDEs0D 2305 LD (AUTO),A - 0C56 2Ar43s03 2306 LD HL,(PARAMS) ; GET DRIVE SPECIFIED. - 0C59 7E 2307 LD A,(HL) - 0C5A E6 1F 2308 AND #0x1F ; LOOK AT LOWER 5 BITS. - 0C5C 3D 2309 DEC A ; ADJUST FOR (1=A, 2=B) ETC. - 0C5D 32rD6s0D 2310 LD (EPARAM),A ; AND SAVE FOR THE SELECT ROUTINE. - 0C60 FE 1E 2311 CP #0x1E ; CHECK FOR 'NO CHANGE' CONDITION. - 0C62 D2r75s0C 2312 JP NC,AUTOSL1 ; YES, DON'T CHANGE. - 0C65 3Ar42s03 2313 LD A,(ACTIVE) ; WE MUST CHANGE, SAVE CURRENTLY ACTIVE - 0C68 32rDFs0D 2314 LD (OLDDRV),A ; DRIVE. - 0C6B 7E 2315 LD A,(HL) ; AND SAVE FIRST BYTE OF FCB ALSO. - 0C6C 32rE0s0D 2316 LD (AUTOFLAG),A ; THIS MUST BE NON-ZERO. - 0C6F E6 E0 2317 AND #0x0E0 ; WHATS THIS FOR (BITS 6,7 ARE USED FOR - 0C71 77 2318 LD (HL),A ; SOMETHING)? - 0C72 CDr45s0C 2319 CALL SETDSK ; SELECT AND LOG IN THIS DRIVE. - 0C75 3Ar41s03 2320 AUTOSL1:LD A,(USERNO) ; MOVE USER NUMBER INTO FCB. - 0C78 2Ar43s03 2321 LD HL,(PARAMS) ; (* UPPER HALF OF FIRST BYTE *) - 0C7B B6 2322 OR (HL) - 0C7C 77 2323 LD (HL),A - 0C7D C9 2324 RET ; AND RETURN (ALL DONE). - 2325 ; - 2326 ; FUNCTION TO RETURN THE CURRENT CP/M VERSION NUMBER. - 2327 ; - 0C7E 3E 22 2328 GETVER: LD A,#0x022 ; VERSION 2.2 - 0C80 C3r01s03 2329 JP SETSTAT - 2330 ; - 2331 ; FUNCTION TO RESET THE DISK SYSTEM. - 2332 ; - 0C83 21 00 00 2333 RSTDSK: LD HL,#0 ; CLEAR WRITE PROTECT STATUS AND LOG - 0C86 22rADs0D 2334 LD (WRTPRT),HL ; IN VECTOR. - 0C89 22rAFs0D 2335 LD (LOGIN),HL - 0C8C AF 2336 XOR A ; SELECT DRIVE 'A'. - 0C8D 32r42s03 2337 LD (ACTIVE),A - 0C90 21 80 00 2338 LD HL,#TBUFF ; SETUP DEFAULT DMA ADDRESS. - 0C93 22rB1s0D 2339 LD (USERDMA),HL - 0C96 CDrDAs05 2340 CALL DEFDMA - 0C99 C3r21s0C 2341 JP LOGINDRV ; NOW LOG IN DRIVE 'A'. - 2342 ; - 2343 ; FUNCTION TO OPEN A SPECIFIED FILE. - 2344 ; - 0C9C CDr72s05 2345 OPENFIL:CALL CLEARS2 ; CLEAR 'S2' BYTE. - 0C9F CDr51s0C 2346 CALL AUTOSEL ; SELECT PROPER DISK. - 0CA2 C3r51s08 2347 JP OPENIT ; AND OPEN THE FILE. - 2348 ; - 2349 ; FUNCTION TO CLOSE A SPECIFIED FILE. - 2350 ; - 0CA5 2351 CLOSEFIL: - 0CA5 CDr51s0C 2352 CALL AUTOSEL ; SELECT PROPER DISK. - 0CA8 C3rA2s08 2353 JP CLOSEIT ; AND CLOSE THE FILE. - 2354 ; - 2355 ; FUNCTION TO RETURN THE FIRST OCCURENCE OF A SPECIFIED FILE - 2356 ; NAME. IF THE FIRST BYTE OF THE FCB IS '?' THEN THE NAME WILL - 2357 ; NOT BE CHECKED (GET THE FIRST ENTRY NO MATTER WHAT). - 2358 ; - 0CAB 0E 00 2359 GETFST: LD C,#0 ; PREPARE FOR SPECIAL SEARCH. - 0CAD EB 2360 EX DE,HL - 0CAE 7E 2361 LD A,(HL) ; IS FIRST BYTE A '?'? - 0CAF FE 3F 2362 CP #QUESTION - 0CB1 CArC2s0C 2363 JP Z,GETFST1 ; YES, JUST GET VERY FIRST ENTRY (ZERO LENGTH MATCH). - 0CB4 CDrA6s04 2364 CALL SETEXT ; GET THE EXTENSION BYTE FROM FCB. - 0CB7 7E 2365 LD A,(HL) ; IS IT '?'? IF YES, THEN WE WANT - 0CB8 FE 3F 2366 CP #QUESTION ; AN ENTRY WITH A SPECIFIC 'S2' BYTE. - 0CBA C4r72s05 2367 CALL NZ,CLEARS2 ; OTHERWISE, LOOK FOR A ZERO 'S2' BYTE. - 0CBD CDr51s0C 2368 CALL AUTOSEL ; SELECT PROPER DRIVE. - 0CC0 0E 0F 2369 LD C,#15 ; COMPARE BYTES 0-14 IN FCB (12&13 EXCLUDED). - 0CC2 CDr18s07 2370 GETFST1:CALL FINDFST ; FIND AN ENTRY AND THEN MOVE IT INTO - 0CC5 C3rE9s05 2371 JP MOVEDIR ; THE USERS DMA SPACE. - 2372 ; - 2373 ; FUNCTION TO RETURN THE NEXT OCCURENCE OF A FILE NAME. - 2374 ; - 0CC8 2ArD9s0D 2375 GETNXT: LD HL,(SAVEFCB) ; RESTORE POINTERS. NOTE THAT NO - 0CCB 22r43s03 2376 LD (PARAMS),HL ; OTHER .DBOS CALLS ARE ALLOWED. - 0CCE CDr51s0C 2377 CALL AUTOSEL ; NO ERROR WILL BE RETURNED, BUT THE - 0CD1 CDr2Ds07 2378 CALL FINDNXT ; RESULTS WILL BE WRONG. - 0CD4 C3rE9s05 2379 JP MOVEDIR - 2380 ; - 2381 ; FUNCTION TO DELETE A FILE BY NAME. - 2382 ; - 0CD7 CDr51s0C 2383 DELFILE:CALL AUTOSEL ; SELECT PROPER DRIVE. - 0CDA CDr9Cs07 2384 CALL ERAFILE ; ERASE THE FILE. - 0CDD C3r01s07 2385 JP STSTATUS ; SET STATUS AND RETURN. - 2386 ; - 2387 ; FUNCTION TO EXECUTE A S.EQUENTIAL READ OF THE SPECIFIED - 2388 ; RECORD NUMBER. - 2389 ; - 0CE0 CDr51s0C 2390 READSEQ:CALL AUTOSEL ; SELECT PROPER DRIVE THEN READ. - 0CE3 C3rBCs09 2391 JP RDSEQ - 2392 ; - 2393 ; FUNCTION TO WRITE THE NET S.EQUENTIAL RECORD. - 2394 ; - 0CE6 CDr51s0C 2395 WRTSEQ: CALL AUTOSEL ; SELECT PROPER DRIVE THEN WRITE. - 0CE9 C3rFEs09 2396 JP WTSEQ - 2397 ; - 2398 ; CREATE A FILE FUNCTION. - 2399 ; - 0CEC CDr72s05 2400 FCREATE:CALL CLEARS2 ; CLEAR THE 'S2' BYTE ON ALL CREATES. - 0CEF CDr51s0C 2401 CALL AUTOSEL ; SELECT PROPER DRIVE AND GET THE NEXT - 0CF2 C3r24s09 2402 JP GETEMPTY ; EMPTY DIRECTORY SPACE. - 2403 ; - 2404 ; FUNCTION TO RENAME A FILE. - 2405 ; - 0CF5 CDr51s0C 2406 RENFILE:CALL AUTOSEL ; SELECT PROPER DRIVE AND THEN SWITCH - 0CF8 CDr16s08 2407 CALL CHGNAMES ; FILE NAMES. - 0CFB C3r01s07 2408 JP STSTATUS - 2409 ; - 2410 ; FUNCTION TO RETURN THE LOGIN VECTOR. - 2411 ; - 0CFE 2ArAFs0D 2412 GETLOG: LD HL,(LOGIN) - 0D01 C3r29s0D 2413 JP GETPRM1 - 2414 ; - 2415 ; FUNCTION TO RETURN THE CURRENT DISK ASSIGNMENT. - 2416 ; - 0D04 3Ar42s03 2417 GETCRNT:LD A,(ACTIVE) - 0D07 C3r01s03 2418 JP SETSTAT - 2419 ; - 2420 ; FUNCTION TO SET THE DMA ADDRESS. - 2421 ; - 0D0A EB 2422 PUTDMA: EX DE,HL - 0D0B 22rB1s0D 2423 LD (USERDMA),HL ; SAVE IN OUR SPACE AND THEN GET TO - 0D0E C3rDAs05 2424 JP DEFDMA ; THE BIOS WITH THIS ALSO. - 2425 ; - 2426 ; FUNCTION TO RETURN THE ALLOCATION VECTOR. - 2427 ; - 0D11 2ArBFs0D 2428 GETALOC:LD HL,(ALOCVECT) - 0D14 C3r29s0D 2429 JP GETPRM1 - 2430 ; - 2431 ; FUNCTION TO RETURN THE READ-ONLY STATUS VECTOR. - 2432 ; - 0D17 2ArADs0D 2433 GETROV: LD HL,(WRTPRT) - 0D1A C3r29s0D 2434 JP GETPRM1 - 2435 ; - 2436 ; FUNCTION TO SET THE FILE ATTRIBUTES (READ-ONLY, SYSTEM). - 2437 ; - 0D1D CDr51s0C 2438 SETATTR:CALL AUTOSEL ; SELECT PROPER DRIVE THEN SAVE ATTRIBUTES. - 0D20 CDr3Bs08 2439 CALL SAVEATTR - 0D23 C3r01s07 2440 JP STSTATUS - 2441 ; - 2442 ; FUNCTION TO RETURN THE ADDRESS OF THE DISK PARAMETER BLOCK - 2443 ; FOR THE CURRENT DRIVE. - 2444 ; - 0D26 2ArBBs0D 2445 GETPARM:LD HL,(DISKPB) - 0D29 22r45s03 2446 GETPRM1:LD (STATUS),HL - 0D2C C9 2447 RET - 2448 ; - 2449 ; FUNCTION TO GET OR SET THE USER NUMBER. IF (E) WAS (FF) - 2450 ; THEN THIS IS A R.EQUEST TO RETURN THE CURRENT USER NUMBER. - 2451 ; ELSE SET THE USER NUMBER FROM (E). - 2452 ; - 0D2D 3ArD6s0D 2453 GETUSER:LD A,(EPARAM) ; GET PARAMETER. - 0D30 FE FF 2454 CP #0x0FF ; GET USER NUMBER? - 0D32 C2r3Bs0D 2455 JP NZ,SETUSER - 0D35 3Ar41s03 2456 LD A,(USERNO) ; YES, JUST DO IT. - 0D38 C3r01s03 2457 JP SETSTAT - 0D3B E6 1F 2458 SETUSER:AND #0x1F ; NO, WE SHOULD SET IT INSTEAD. KEEP LOW - 0D3D 32r41s03 2459 LD (USERNO),A ; BITS (0-4) ONLY. - 0D40 C9 2460 RET - 2461 ; - 2462 ; FUNCTION TO READ A RANDOM RECORD FROM A FILE. - 2463 ; - 0D41 2464 RDRANDOM: - 0D41 CDr51s0C 2465 CALL AUTOSEL ; SELECT PROPER DRIVE AND READ. - 0D44 C3r93s0B 2466 JP READRAN - 2467 ; - 2468 ; FUNCTION TO COMPUTE THE FILE SIZE FOR RANDOM FILES. - 2469 ; - 0D47 2470 WTRANDOM: - 0D47 CDr51s0C 2471 CALL AUTOSEL ; SELECT PROPER DRIVE AND WRITE. - 0D4A C3r9Cs0B 2472 JP WRITERAN - 2473 ; - 2474 ; FUNCTION TO COMPUTE THE SIZE OF A RANDOM FILE. - 2475 ; - 0D4D 2476 FILESIZE: - 0D4D CDr51s0C 2477 CALL AUTOSEL ; SELECT PROPER DRIVE AND CHECK FILE LENGTH - 0D50 C3rD2s0B 2478 JP RANSIZE - 2479 ; - 2480 ; FUNCTION #37. THIS ALLOWS A PROGRAM TO LOG OFF ANY DRIVES. - 2481 ; ON ENTRY, SET (DE) TO CONTAIN A WORD WITH BITS SET FOR THOSE - 2482 ; DRIVES THAT ARE TO BE LOGGED OFF. THE LOG-IN VECTOR AND THE - 2483 ; WRITE PROTECT VECTOR WILL BE UPDATED. THIS MUST BE A M/PM - 2484 ; SPECIAL FUNCTION. - 2485 ; - 0D53 2Ar43s03 2486 LOGOFF: LD HL,(PARAMS) ; GET DRIVES TO LOG OFF. - 0D56 7D 2487 LD A,L ; FOR EACH BIT THAT IS SET, WE WANT - 0D57 2F 2488 CPL ; TO CLEAR THAT BIT IN (LOGIN) - 0D58 5F 2489 LD E,A ; AND (WRTPRT). - 0D59 7C 2490 LD A,H - 0D5A 2F 2491 CPL - 0D5B 2ArAFs0D 2492 LD HL,(LOGIN) ; RESET THE LOGIN VECTOR. - 0D5E A4 2493 AND H - 0D5F 57 2494 LD D,A - 0D60 7D 2495 LD A,L - 0D61 A3 2496 AND E - 0D62 5F 2497 LD E,A - 0D63 2ArADs0D 2498 LD HL,(WRTPRT) - 0D66 EB 2499 EX DE,HL - 0D67 22rAFs0D 2500 LD (LOGIN),HL ; AND SAVE. - 0D6A 7D 2501 LD A,L ; NOW DO THE WRITE PROTECT VECTOR. - 0D6B A3 2502 AND E - 0D6C 6F 2503 LD L,A - 0D6D 7C 2504 LD A,H - 0D6E A2 2505 AND D - 0D6F 67 2506 LD H,A - 0D70 22rADs0D 2507 LD (WRTPRT),HL ; AND SAVE. ALL DONE. - 0D73 C9 2508 RET - 2509 ; - 2510 ; GET HERE TO RETURN TO THE USER. - 2511 ; - 0D74 3ArDEs0D 2512 GOBACK: LD A,(AUTO) ; WAS AUTO SELECT ACTIVATED? - 0D77 B7 2513 OR A - 0D78 CAr91s0D 2514 JP Z,GOBACK1 - 0D7B 2Ar43s03 2515 LD HL,(PARAMS) ; YES, BUT WAS A CHANGE MADE? - 0D7E 36 00 2516 LD (HL),#0 ; (* RESET FIRST BYTE OF FCB *) - 0D80 3ArE0s0D 2517 LD A,(AUTOFLAG) - 0D83 B7 2518 OR A - 0D84 CAr91s0D 2519 JP Z,GOBACK1 - 0D87 77 2520 LD (HL),A ; YES, RESET FIRST BYTE PROPERLY. - 0D88 3ArDFs0D 2521 LD A,(OLDDRV) ; AND GET THE OLD DRIVE AND SELECT IT. - 0D8B 32rD6s0D 2522 LD (EPARAM),A - 0D8E CDr45s0C 2523 CALL SETDSK - 0D91 2Ar0Fs03 2524 GOBACK1:LD HL,(USRSTACK) ; RESET THE USERS STACK POINTER. - 0D94 F9 2525 LD SP,HL - 0D95 2Ar45s03 2526 LD HL,(STATUS) ; GET RETURN STATUS. - 0D98 7D 2527 LD A,L ; FORCE VERSION 1.4 COMPATABILITY. - 0D99 44 2528 LD B,H - 0D9A C9 2529 RET ; AND GO BACK TO USER. - 2530 ; - 2531 ; FUNCTION #40. THIS IS A SPECIAL ENTRY TO DO RANDOM I/O. - 2532 ; FOR THE CASE WHERE WE ARE WRITING TO UNUSED DISK SPACE, THIS - 2533 ; SPACE WILL BE ZEROED OUT FIRST. THIS MUST BE A M/PM SPECIAL - 2534 ; PURPOSE FUNCTION, BECAUSE WHY WOULD ANY NORMAL PROGRAM EVEN - 2535 ; CARE ABOUT THE PREVIOUS CONTENTS OF A SECTOR ABOUT TO BE - 2536 ; WRITTEN OVER. - 2537 ; - 0D9B CDr51s0C 2538 WTSPECL:CALL AUTOSEL ; SELECT PROPER DRIVE. - 0D9E 3E 02 2539 LD A,#2 ; USE SPECIAL WRITE MODE. - 0DA0 32rD5s0D 2540 LD (MODE),A - 0DA3 0E 00 2541 LD C,#0 ; SET WRITE INDICATOR. - 0DA5 CDr07s0B 2542 CALL POSITN1 ; POSITION THE FILE. - 0DA8 CCr03s0A 2543 CALL Z,WTSEQ1 ; AND WRITE (IF NO ERRORS). - 0DAB C9 2544 RET - 2545 ; - 2546 ;************************************************************** - 2547 ;* - 2548 ;* BDOS DATA STORAGE POOL. - 2549 ;* - 2550 ;************************************************************** - 2551 ; - 0DAC 2552 EMPTYFCB: - 0DAC E5 2553 .DB 0x0E5 ; EMPTY DIRECTORY SEGMENT INDICATOR. - 0DAD 00 00 2554 WRTPRT: .DW 0 ; WRITE PROTECT STATUS FOR ALL 16 DRIVES. - 0DAF 00 00 2555 LOGIN: .DW 0 ; DRIVE ACTIVE WORD (1 BIT PER DRIVE). - 0DB1 80 00 2556 USERDMA:.DW 0x80 ; USER'S DMA ADDRESS (DEFAULTS TO 80H). - 2557 ; - 2558 ; SCRATCH AREAS FROM PARAMETER BLOCK. - 2559 ; - 0DB3 2560 SCRATCH1: - 0DB3 00 00 2561 .DW 0 ; RELATIVE POSITION WITHIN DIR SEGMENT FOR FILE (0-3). - 0DB5 2562 SCRATCH2: - 0DB5 00 00 2563 .DW 0 ; LAST SELECTED TRACK NUMBER. - 0DB7 2564 SCRATCH3: - 0DB7 00 00 2565 .DW 0 ; LAST SELECTED SECTOR NUMBER. - 2566 ; - 2567 ; DISK STORAGE AREAS FROM PARAMETER BLOCK. - 2568 ; - 0DB9 00 00 2569 DIRBUF: .DW 0 ; ADDRESS OF DIRECTORY BUFFER TO USE. - 0DBB 00 00 2570 DISKPB: .DW 0 ; CONTAINS ADDRESS OF DISK PARAMETER BLOCK. - 0DBD 00 00 2571 CHKVECT:.DW 0 ; ADDRESS OF CHECK VECTOR. - 0DBF 2572 ALOCVECT: - 0DBF 00 00 2573 .DW 0 ; ADDRESS OF ALLOCATION VECTOR (BIT MAP). - 2574 ; - 2575 ; PARAMETER BLOCK RETURNED FROM THE BIOS. - 2576 ; - 0DC1 00 00 2577 SECTORS:.DW 0 ; SECTORS PER TRACK FROM BIOS. - 0DC3 00 2578 BLKSHFT:.DB 0 ; BLOCK SHIFT. - 0DC4 00 2579 BLKMASK:.DB 0 ; BLOCK MASK. - 0DC5 00 2580 EXTMASK:.DB 0 ; EXTENT MASK. - 0DC6 00 00 2581 DSKSIZE:.DW 0 ; DISK SIZE FROM BIOS (NUMBER OF BLOCKS-1). - 0DC8 00 00 2582 DIRSIZE:.DW 0 ; DIRECTORY SIZE. - 0DCA 00 00 2583 ALLOC0: .DW 0 ; STORAGE FOR FIRST BYTES OF BIT MAP (DIR SPACE USED). - 0DCC 00 00 2584 ALLOC1: .DW 0 - 0DCE 00 00 2585 OFFSET: .DW 0 ; FIRST USABLE TRACK NUMBER. - 0DD0 00 00 2586 XLATE: .DW 0 ; SECTOR TRANSLATION TABLE ADDRESS. - 2587 ; - 2588 ; - 0DD2 2589 CLOSEFLG: - 0DD2 00 2590 .DB 0 ; CLOSE FLAG (=0FFH IS EXTENT WRITTEN OK). - 0DD3 2591 R.DWRTFLG: - 0DD3 00 2592 .DB 0 ; READ/WRITE FLAG (0FFH=READ, 0=WRITE). - 0DD4 00 2593 FNDSTAT:.DB 0 ; FILENAME FOUND STATUS (0=FOUND FIRST ENTRY). - 0DD5 00 2594 MODE: .DB 0 ; I/O MODE SELECT (0=RANDOM, 1=S.EQUENTIAL, 2=SPECIAL RANDOM). - 0DD6 00 2595 EPARAM: .DB 0 ; STORAGE FOR REGISTER (E) ON ENTRY TO BDOS. - 0DD7 2596 RELBLOCK: - 0DD7 00 2597 .DB 0 ; RELATIVE POSITION WITHIN FCB OF BLOCK NUMBER WRITTEN. - 0DD8 00 2598 COUNTER:.DB 0 ; BYTE COUNTER FOR DIRECTORY NAME SEARCHES. - 0DD9 00 00 00 00 2599 SAVEFCB:.DW 0,0 ; SAVE SPACE FOR ADDRESS OF FCB (FOR DIRECTORY SEARCHES). - 0DDD 00 2600 BIGDISK:.DB 0 ; IF =0 THEN DISK IS > 256 BLOCKS LONG. - 0DDE 00 2601 AUTO: .DB 0 ; IF NON-ZERO, THEN AUTO SELECT ACTIVATED. - 0DDF 00 2602 OLDDRV: .DB 0 ; ON AUTO SELECT, STORAGE FOR PREVIOUS DRIVE. - 0DE0 2603 AUTOFLAG: - 0DE0 00 2604 .DB 0 ; IF NON-ZERO, THEN AUTO SELECT CHANGED DRIVES. - 0DE1 00 2605 SAVNXT: .DB 0 ; STORAGE FOR NEXT RECORD NUMBER TO ACCESS. - 0DE2 00 2606 SAVEXT: .DB 0 ; STORAGE FOR EXTENT NUMBER OF FILE. - 0DE3 00 00 2607 SAVNREC:.DW 0 ; STORAGE FOR NUMBER OF RECORDS IN FILE. - 0DE5 00 00 2608 BLKNMBR:.DW 0 ; BLOCK NUMBER (PHYSICAL SECTOR) USED WITHIN A FILE OR LOGICAL SEC - 0DE7 00 00 2609 LOGSECT:.DW 0 ; STARTING LOGICAL (128 BYTE) SECTOR OF BLOCK (PHYSICAL SECTOR). - 0DE9 00 2610 FCBPOS: .DB 0 ; RELATIVE POSITION WITHIN BUFFER FOR FCB OF FILE OF INTEREST. - 0DEA 00 00 2611 FILEPOS:.DW 0 ; FILES POSITION WITHIN DIRECTORY (0 TO MAX ENTRIES -1). - 2612 ; - 2613 ; DISK DIRECTORY BUFFER CHECKSUM BYTES. ONE FOR EACH OF THE - 2614 ; 16 POSSIBLE DRIVES. - 2615 ; - 0DEC 2616 CKSUMTBL: - 0DEC 00 00 00 00 00 00 2617 .DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - 00 00 00 00 00 00 - 00 00 00 00 - 2618 ; - 2619 ;************************************************************** - 2620 ;* - 2621 ;* B I O S J U M P T A B L E - 2622 ;* - 2623 ;************************************************************** - 2624 ; - 2625 - E600 2626 BIOS = BIOSO ;BIOS ORIGIN - 2627 ; - E600 2628 BOOT = BIOS ;(BOOT) Cold boot entry - E603 2629 WBOOT = BIOS+3 ;Warm boot entry - E606 2630 CONST = BIOS+6 ;Console status - E609 2631 CONIN = BIOS+9 ;Console char in - E60C 2632 CONOUT = BIOS+12 ;Console char out - E60F 2633 LIST = BIOS+15 ;List char out - E612 2634 PUNCH = BIOS+18 ;Punch char out - E615 2635 READER = BIOS+21 ;Reader char in - E618 2636 HOME = BIOS+24 ;Home disk - E61B 2637 SELDSK = BIOS+27 ;Select disk - E61E 2638 SETTRK = BIOS+30 ;Set disk track addr - E621 2639 SETSEC = BIOS+33 ;Set disk sector addr - E624 2640 SETDMA = BIOS+36 ;Set DMA buffer addr - E627 2641 READ = BIOS+39 ;Read sector - E62A 2642 WRITE = BIOS+42 ;Write sector - E630 2643 SECTRN = BIOS+48 ;Sector translation routine - 2644 ; - 2645 ;dwg; .IF ENDFIL - 2646 ;dwg; .ORG BDOSO+0DFFH - 2647 ;dwg; .DB 55H - 2648 ;dwg; .ENDIF - 2649 - 2650 ;dwg; .END - 2651 - 0DFC 2652 _bdos_end:: - 2653 .area _CODE - 2654 .area _CABS diff --git a/doug/src/bdosb01.rel b/doug/src/bdosb01.rel deleted file mode 100755 index 9c37b3e5..00000000 --- a/doug/src/bdosb01.rel +++ /dev/null @@ -1,714 +0,0 @@ -XL -H 8 areas 4 global symbols -M bdosb01 -O -mz80 -S .__.ABS. Def0000 -A _CODE size 0 flags 0 addr 0 -S _bdos Def0000 -S _bdos_start Def0000 -A _DATA size 0 flags 0 addr 0 -A _OVERLAY size 0 flags 0 addr 0 -A _HOME size 0 flags 0 addr 0 -A _GSINIT size 0 flags 0 addr 0 -A _GSFINAL size 0 flags 0 addr 0 -A _BDOSB01 size DFC flags 0 addr 0 -S _bdos_end Def0DFC -A _CABS size 0 flags 0 addr 0 -T 00 00 -R 00 00 00 00 -T 00 00 -R 00 00 00 00 -T 00 00 00 00 00 00 00 00 C3 11 00 99 00 A5 00 -R 00 00 06 00 00 09 06 00 00 0B 06 00 00 0D 06 00 -T 0D 00 AB 00 B1 00 EB 22 43 03 EB 7B 32 -R 00 00 06 00 00 02 06 00 00 04 06 00 00 08 06 00 -T 18 00 D6 0D 21 00 00 22 45 03 39 22 0F 03 31 -R 00 00 06 00 00 02 06 00 00 08 06 00 00 0C 06 00 -T 25 00 41 03 AF 32 E0 0D 32 DE 0D 21 -R 00 00 06 00 00 02 06 00 00 06 06 00 00 09 06 00 -T 2F 00 74 0D E5 79 FE 29 D0 4B 21 47 00 5F 16 00 -R 00 00 06 00 00 02 06 00 00 0B 06 00 -T 3D 00 19 19 5E 23 56 2A 43 03 EB E9 03 E6 C8 02 -R 00 00 06 00 00 08 06 00 00 0E 06 00 -T 4B 00 90 01 CE 02 12 E6 0F E6 D4 02 -R 00 00 06 00 00 02 06 00 00 04 06 00 00 0A 06 00 -T 55 00 ED 02 F3 02 F8 02 -R 00 00 06 00 00 02 06 00 00 04 06 00 00 06 06 00 -T 5B 00 E1 01 FE 02 7E 0C -R 00 00 06 00 00 02 06 00 00 04 06 00 00 06 06 00 -T 61 00 83 0C 45 0C 9C 0C -R 00 00 06 00 00 02 06 00 00 04 06 00 00 06 06 00 -T 67 00 A5 0C AB 0C C8 0C -R 00 00 06 00 00 02 06 00 00 04 06 00 00 06 06 00 -T 6D 00 D7 0C E0 0C E6 0C -R 00 00 06 00 00 02 06 00 00 04 06 00 00 06 06 00 -T 73 00 EC 0C F5 0C FE 0C -R 00 00 06 00 00 02 06 00 00 04 06 00 00 06 06 00 -T 79 00 04 0D 0A 0D 11 0D -R 00 00 06 00 00 02 06 00 00 04 06 00 00 06 06 00 -T 7F 00 2C 05 17 0D 1D 0D -R 00 00 06 00 00 02 06 00 00 04 06 00 00 06 06 00 -T 85 00 26 0D 2D 0D 41 0D -R 00 00 06 00 00 02 06 00 00 04 06 00 00 06 06 00 -T 8B 00 47 0D 4D 0D 0E 0C -R 00 00 06 00 00 02 06 00 00 04 06 00 00 06 06 00 -T 91 00 53 0D 04 03 04 03 -R 00 00 06 00 00 02 06 00 00 04 06 00 00 06 06 00 -T 97 00 9B 0D 21 CA 00 CD E5 00 FE 03 CA 00 00 C9 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T A5 00 21 D5 00 C3 B4 00 21 E1 00 C3 -R 00 00 06 00 00 03 06 00 00 06 06 00 00 09 06 00 -T AF 00 B4 00 21 DC 00 CD E5 00 C3 00 00 42 44 4F -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T BD 00 53 20 45 52 52 20 4F 4E 20 20 3A 20 24 42 -R 00 00 06 00 -T CB 00 41 44 20 53 45 43 54 4F 52 24 53 45 4C 45 -R 00 00 06 00 -T D9 00 43 54 24 46 49 4C 45 20 52 2F 4F 24 E5 CD -R 00 00 06 00 -T E7 00 C9 01 3A 42 03 C6 41 32 C6 00 01 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 0A 06 00 -T F2 00 BA 00 CD D3 01 C1 CD D3 01 21 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 09 06 00 -T FC 00 0E 03 7E 36 00 B7 C0 C3 09 E6 CD FB 00 CD -R 00 00 06 00 00 02 06 00 00 0D 06 00 -T 0A 01 14 01 D8 F5 4F CD 90 01 F1 C9 FE 0D C8 FE -R 00 00 06 00 00 02 06 00 00 08 06 00 -T 18 01 0A C8 FE 09 C8 FE 08 C8 FE 20 C9 -R 00 00 06 00 -T 23 01 -R 00 00 06 00 -T 23 01 3A 0E 03 B7 C2 45 01 CD 06 E6 E6 01 C8 CD -R 00 00 06 00 00 03 06 00 00 07 06 00 -T 31 01 09 E6 FE 13 C2 42 01 CD 09 E6 FE 03 CA -R 00 00 06 00 00 07 06 00 -T 3E 01 00 00 AF C9 32 0E 03 3E 01 C9 3A 0A 03 B7 -R 00 00 06 00 00 07 06 00 00 0D 06 00 -T 4C 01 C2 62 01 C5 CD 23 01 C1 C5 CD 0C E6 C1 C5 -R 00 00 06 00 00 03 06 00 00 07 06 00 -T 5A 01 3A 0D 03 B7 C4 0F E6 C1 79 21 0C 03 FE 7F -R 00 00 06 00 00 03 06 00 00 0C 06 00 -T 68 01 C8 34 FE 20 D0 35 7E B7 C8 79 FE 08 C2 -R 00 00 06 00 -T 75 01 79 01 35 C9 FE 0A C0 36 00 C9 79 CD 14 01 -R 00 00 06 00 00 02 06 00 00 0E 06 00 -T 83 01 D2 90 01 F5 0E 5E CD 48 01 F1 F6 40 4F 79 -R 00 00 06 00 00 03 06 00 00 09 06 00 -T 91 01 FE 09 C2 48 01 0E 20 CD 48 01 3A 0C 03 E6 -R 00 00 06 00 00 05 06 00 00 0A 06 00 00 0D 06 00 -T 9F 01 07 C2 96 01 C9 CD AC 01 0E 20 CD 0C E6 0E -R 00 00 06 00 00 04 06 00 00 08 06 00 -T AD 01 08 C3 0C E6 0E 23 CD 48 01 CD C9 01 3A -R 00 00 06 00 00 09 06 00 00 0C 06 00 -T BA 01 0C 03 21 0B 03 BE D0 0E 20 CD 48 01 C3 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 0C 06 00 -T C7 01 B9 01 0E 0D CD 48 01 0E 0A C3 48 01 0A FE -R 00 00 06 00 00 02 06 00 00 07 06 00 00 0C 06 00 -T D5 01 24 C8 03 C5 4F CD 90 01 C1 C3 D3 01 3A -R 00 00 06 00 00 08 06 00 00 0C 06 00 -T E2 01 0C 03 32 0B 03 2A 43 03 4E 23 E5 06 00 C5 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T F0 01 E5 CD FB 00 E6 7F E1 C1 FE 0D CA C1 02 FE -R 00 00 06 00 00 04 06 00 00 0D 06 00 -T FE 01 0A CA C1 02 FE 08 C2 16 02 78 B7 CA EF 01 -R 00 00 06 00 00 04 06 00 00 09 06 00 00 0E 06 00 -T 0C 02 05 3A 0C 03 32 0A 03 C3 70 02 FE 7F C2 -R 00 00 06 00 00 04 06 00 00 07 06 00 00 0A 06 00 -T 19 02 26 02 78 B7 CA EF 01 7E 05 2B C3 A9 02 FE -R 00 00 06 00 00 02 06 00 00 07 06 00 00 0D 06 00 -T 27 02 05 C2 37 02 C5 E5 CD C9 01 AF 32 0B 03 C3 -R 00 00 06 00 00 04 06 00 00 09 06 00 00 0D 06 00 -T 35 02 F1 01 FE 10 C2 48 02 E5 21 0D 03 3E 01 96 -R 00 00 06 00 00 02 06 00 00 07 06 00 00 0B 06 00 -T 43 02 77 E1 C3 EF 01 FE 18 C2 5F 02 E1 3A 0B 03 -R 00 00 06 00 00 05 06 00 00 0A 06 00 00 0E 06 00 -T 51 02 21 0C 03 BE D2 E1 01 35 CD A4 01 C3 -R 00 00 06 00 00 03 06 00 00 07 06 00 00 0B 06 00 -T 5D 02 4E 02 FE 15 C2 6B 02 CD B1 01 E1 C3 -R 00 00 06 00 00 02 06 00 00 07 06 00 00 0A 06 00 -T 69 02 E1 01 FE 12 C2 A6 02 C5 CD B1 01 C1 E1 E5 -R 00 00 06 00 00 02 06 00 00 07 06 00 00 0B 06 00 -T 77 02 C5 78 B7 CA 8A 02 23 4E 05 C5 E5 CD 7F 01 -R 00 00 06 00 00 06 06 00 00 0E 06 00 -T 85 02 E1 C1 C3 78 02 E5 3A 0A 03 B7 CA F1 01 21 -R 00 00 06 00 00 05 06 00 00 09 06 00 00 0D 06 00 -T 93 02 0C 03 96 32 0A 03 CD A4 01 21 -R 00 00 06 00 00 02 06 00 00 06 06 00 00 09 06 00 -T 9D 02 0A 03 35 C2 99 02 C3 F1 01 23 77 04 C5 E5 -R 00 00 06 00 00 02 06 00 00 06 06 00 00 09 06 00 -T AB 02 4F CD 7F 01 E1 C1 7E FE 03 78 C2 BD 02 FE -R 00 00 06 00 00 04 06 00 00 0D 06 00 -T B9 02 01 CA 00 00 B9 DA EF 01 E1 70 0E 0D C3 -R 00 00 06 00 00 08 06 00 -T C6 02 48 01 CD 06 01 C3 01 03 CD 15 E6 C3 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T D2 02 01 03 79 3C CA E0 02 3C CA 06 E6 C3 0C E6 -R 00 00 06 00 00 02 06 00 00 07 06 00 -T E0 02 CD 06 E6 B7 CA 91 0D CD 09 E6 C3 01 03 3A -R 00 00 06 00 00 07 06 00 00 0D 06 00 -T EE 02 03 00 C3 01 03 21 03 00 71 C9 EB 4D 44 C3 -R 00 00 06 00 00 05 06 00 -T FC 02 D3 01 CD 23 01 32 45 03 C9 3E 01 C3 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 08 03 01 03 00 -R 00 00 06 00 00 02 06 00 -T 0B 03 -R 00 00 06 00 -T 0B 03 02 00 00 00 -R 00 00 06 00 -T 0F 03 -R 00 00 06 00 -T 0F 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -R 00 00 06 00 -T 1D 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -R 00 00 06 00 -T 2B 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -R 00 00 06 00 -T 39 03 00 00 00 00 00 00 00 00 -R 00 00 06 00 -T 41 03 -R 00 00 06 00 -T 41 03 00 00 00 00 00 00 21 0B 00 5E 23 56 EB E9 -R 00 00 06 00 00 09 06 00 -T 4F 03 0C 0D C8 1A 77 13 23 C3 50 03 3A 42 03 4F -R 00 00 06 00 00 0A 06 00 00 0D 06 00 -T 5D 03 CD 1B E6 7C B5 C8 5E 23 56 23 22 B3 0D 23 -R 00 00 06 00 00 0D 06 00 -T 6B 03 23 22 B5 0D 23 23 22 B7 0D 23 23 EB 22 -R 00 00 06 00 00 04 06 00 00 09 06 00 -T 78 03 D0 0D 21 B9 0D 0E 08 CD 4F 03 2A -R 00 00 06 00 00 02 06 00 00 05 06 00 00 0A 06 00 -T 83 03 BB 0D EB 21 C1 0D 0E 0F CD 4F 03 2A -R 00 00 06 00 00 02 06 00 00 06 06 00 00 0B 06 00 -T 8F 03 C6 0D 7C 21 DD 0D 36 FF B7 CA 9D 03 36 00 -R 00 00 06 00 00 02 06 00 00 06 06 00 00 0C 06 00 -T 9D 03 3E FF B7 C9 CD 18 E6 AF 2A B5 0D 77 23 77 -R 00 00 06 00 00 0B 06 00 -T AB 03 2A B7 0D 77 23 77 C9 CD 27 E6 C3 BB 03 CD -R 00 00 06 00 00 03 06 00 00 0D 06 00 -T B9 03 2A E6 B7 C8 21 09 00 C3 4A 03 2A EA 0D 0E -R 00 00 06 00 00 07 06 00 00 0A 06 00 00 0D 06 00 -T C7 03 02 CD EA 04 22 E5 0D 22 EC 0D 21 -R 00 00 06 00 00 04 06 00 00 07 06 00 00 0A 06 00 -T D2 03 E5 0D 4E 23 46 2A B7 0D 5E 23 56 2A B5 0D -R 00 00 06 00 00 02 06 00 00 08 06 00 00 0E 06 00 -T E0 03 7E 23 66 6F 79 93 78 9A D2 FA 03 E5 2A -R 00 00 06 00 00 0B 06 00 -T ED 03 C1 0D 7B 95 5F 7A 9C 57 E1 2B C3 E4 03 E5 -R 00 00 06 00 00 02 06 00 00 0D 06 00 -T FB 03 2A C1 0D 19 DA 0F 04 79 95 78 9C DA 0F 04 -R 00 00 06 00 00 03 06 00 00 07 06 00 00 0E 06 00 -T 09 04 EB E1 23 C3 FA 03 E1 C5 D5 E5 EB 2A CE 0D -R 00 00 06 00 00 06 06 00 00 0E 06 00 -T 17 04 19 44 4D CD 1E E6 D1 2A B5 0D 73 23 72 D1 -R 00 00 06 00 00 0A 06 00 -T 25 04 2A B7 0D 73 23 72 C1 79 93 4F 78 9A 47 2A -R 00 00 06 00 00 03 06 00 -T 33 04 D0 0D EB CD 30 E6 4D 44 C3 21 E6 -R 00 00 06 00 00 02 06 00 -T 3E 04 -R 00 00 06 00 -T 3E 04 21 C3 0D 4E 3A E3 0D B7 1F 0D C2 45 04 47 -R 00 00 06 00 00 03 06 00 00 07 06 00 00 0D 06 00 -T 4C 04 3E 08 96 4F 3A E2 0D 0D CA 5C 04 B7 17 C3 -R 00 00 06 00 00 07 06 00 00 0B 06 00 -T 5A 04 53 04 80 C9 2A 43 03 11 10 00 19 09 3A -R 00 00 06 00 00 02 06 00 00 07 06 00 -T 67 04 DD 0D B7 CA 71 04 6E 26 00 C9 09 5E 23 56 -R 00 00 06 00 00 02 06 00 00 06 06 00 -T 75 04 EB C9 CD 3E 04 4F 06 00 CD 5E 04 22 E5 0D -R 00 00 06 00 00 05 06 00 00 0B 06 00 00 0E 06 00 -T 83 04 C9 2A E5 0D 7D B4 C9 3A C3 0D 2A E5 0D 29 -R 00 00 06 00 00 04 06 00 00 0A 06 00 00 0D 06 00 -T 91 04 3D C2 90 04 22 E7 0D 3A C4 0D 4F 3A -R 00 00 06 00 00 04 06 00 00 07 06 00 00 0A 06 00 -T 9D 04 E3 0D A1 B5 6F 22 E5 0D C9 2A 43 03 11 -R 00 00 06 00 00 02 06 00 00 08 06 00 00 0C 06 00 -T AA 04 0C 00 19 C9 2A 43 03 11 0F 00 19 EB 21 -R 00 00 06 00 00 07 06 00 -T B7 04 11 00 19 C9 CD AE 04 7E 32 E3 0D EB 7E 32 -R 00 00 06 00 00 07 06 00 00 0B 06 00 -T C5 04 E1 0D CD A6 04 3A C5 0D A6 32 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T CF 04 E2 0D C9 CD AE 04 3A D5 0D FE 02 C2 -R 00 00 06 00 00 02 06 00 00 06 06 00 00 09 06 00 -T DB 04 DE 04 AF 4F 3A E3 0D 81 77 EB 3A E1 0D 77 -R 00 00 06 00 00 02 06 00 00 07 06 00 00 0D 06 00 -T E9 04 C9 0C 0D C8 7C B7 1F 67 7D 1F 6F C3 EB 04 -R 00 00 06 00 00 0E 06 00 -T F7 04 -R 00 00 06 00 -T F7 04 0E 80 2A B9 0D AF 86 23 0D C2 FD 04 C9 0C -R 00 00 06 00 00 05 06 00 00 0C 06 00 -T 05 05 0D C8 29 C3 05 05 C5 3A 42 03 4F 21 01 00 -R 00 00 06 00 00 06 06 00 00 0A 06 00 -T 13 05 CD 04 05 C1 79 B5 6F 78 B4 67 C9 2A AD 0D -R 00 00 06 00 00 03 06 00 00 0E 06 00 -T 21 05 3A 42 03 4F CD EA 04 7D E6 01 C9 21 AD 0D -R 00 00 06 00 00 03 06 00 00 07 06 00 00 0E 06 00 -T 2F 05 4E 23 46 CD 0B 05 22 AD 0D 2A C8 0D 23 EB -R 00 00 06 00 00 06 06 00 00 09 06 00 00 0C 06 00 -T 3D 05 2A B3 0D 73 23 72 C9 CD 5E 05 11 09 00 19 -R 00 00 06 00 00 03 06 00 00 0A 06 00 -T 4B 05 7E 17 D0 21 0F 00 C3 4A 03 CD 1E 05 C8 21 -R 00 00 06 00 00 06 06 00 00 09 06 00 00 0C 06 00 -T 59 05 0D 00 C3 4A 03 2A B9 0D 3A -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 62 05 E9 0D 85 6F D0 24 C9 2A 43 03 11 0E 00 19 -R 00 00 06 00 00 02 06 00 00 0A 06 00 -T 70 05 7E C9 CD 69 05 36 00 C9 CD 69 05 F6 80 77 -R 00 00 06 00 00 05 06 00 00 0B 06 00 -T 7E 05 C9 2A EA 0D EB 2A B3 0D 7B 96 23 7A 9E C9 -R 00 00 06 00 00 04 06 00 00 08 06 00 -T 8C 05 CD 7F 05 D8 13 72 2B 73 C9 7B 95 6F 7A 9C -R 00 00 06 00 00 03 06 00 -T 9A 05 67 C9 0E FF -R 00 00 06 00 -T 9E 05 -R 00 00 06 00 -T 9E 05 2A EC 0D EB 2A CC 0D CD 95 05 D0 C5 CD -R 00 00 06 00 00 03 06 00 00 07 06 00 00 0A 06 00 -T AB 05 F7 04 2A BD 0D EB 2A EC 0D 19 C1 0C CA -R 00 00 06 00 00 02 06 00 00 05 06 00 00 09 06 00 -T B8 05 C4 05 BE C8 CD 7F 05 D0 CD 2C 05 C9 77 C9 -R 00 00 06 00 00 02 06 00 00 07 06 00 00 0B 06 00 -T C6 05 -R 00 00 06 00 -T C6 05 CD 9C 05 CD E0 05 0E 01 CD B8 03 C3 -R 00 00 06 00 00 03 06 00 00 06 06 00 00 0B 06 00 -T D2 05 DA 05 CD E0 05 CD B2 03 21 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T DB 05 B1 0D C3 E3 05 21 B9 0D 4E 23 46 C3 24 E6 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T E9 05 2A B9 0D EB 2A B1 0D 0E 80 C3 4F 03 -R 00 00 06 00 00 03 06 00 00 07 06 00 00 0C 06 00 -T F5 05 -R 00 00 06 00 -T F5 05 21 EA 0D 7E 23 BE C0 3C C9 -R 00 00 06 00 00 03 06 00 -T FE 05 -R 00 00 06 00 -T FE 05 21 FF FF 22 EA 0D C9 2A C8 0D EB 2A EA 0D -R 00 00 06 00 00 06 06 00 00 0A 06 00 00 0E 06 00 -T 0C 06 23 22 EA 0D CD 95 05 D2 19 06 C3 -R 00 00 06 00 00 04 06 00 00 07 06 00 00 0A 06 00 -T 17 06 FE 05 3A EA 0D E6 03 06 05 87 05 C2 20 06 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 0E 06 00 -T 25 06 32 E9 0D B7 C0 C5 CD C3 03 CD D4 05 C1 C3 -R 00 00 06 00 00 03 06 00 00 09 06 00 00 0C 06 00 -T 33 06 9E 05 -R 00 00 06 00 00 02 06 00 -T 35 06 -R 00 00 06 00 -T 35 06 79 E6 07 3C 5F 57 79 0F 0F 0F E6 1F 4F 78 -R 00 00 06 00 -T 43 06 87 87 87 87 87 B1 4F 78 0F 0F 0F E6 1F 47 -R 00 00 06 00 -T 51 06 2A BF 0D 09 7E 07 1D C2 56 06 C9 -R 00 00 06 00 00 03 06 00 00 0A 06 00 -T 5C 06 -R 00 00 06 00 -T 5C 06 D5 CD 35 06 E6 FE C1 B1 0F 15 C2 64 06 77 -R 00 00 06 00 00 04 06 00 00 0D 06 00 -T 6A 06 C9 CD 5E 05 11 10 00 19 C5 0E 11 D1 0D C8 -R 00 00 06 00 00 04 06 00 -T 78 06 D5 3A DD 0D B7 CA 88 06 C5 E5 4E 06 00 C3 -R 00 00 06 00 00 04 06 00 00 08 06 00 -T 86 06 8E 06 0D C5 4E 23 46 E5 79 B0 CA 9D 06 2A -R 00 00 06 00 00 02 06 00 00 0D 06 00 -T 94 06 C6 0D 7D 91 7C 98 D4 5C 06 E1 23 C1 C3 -R 00 00 06 00 00 02 06 00 00 09 06 00 -T A1 06 75 06 2A C6 0D 0E 03 CD EA 04 23 44 4D 2A -R 00 00 06 00 00 02 06 00 00 05 06 00 00 0A 06 00 -T AF 06 BF 0D 36 00 23 0B 78 B1 C2 B1 06 2A CA 0D -R 00 00 06 00 00 02 06 00 00 0B 06 00 00 0E 06 00 -T BD 06 EB 2A BF 0D 73 23 72 CD A1 03 2A B3 0D 36 -R 00 00 06 00 00 04 06 00 00 0A 06 00 00 0D 06 00 -T CB 06 03 23 36 00 CD FE 05 0E FF CD 05 06 CD -R 00 00 06 00 00 07 06 00 00 0C 06 00 -T D8 06 F5 05 C8 CD 5E 05 3E E5 BE CA D2 06 3A -R 00 00 06 00 00 02 06 00 00 06 06 00 00 0C 06 00 -T E5 06 41 03 BE C2 F6 06 23 7E D6 24 C2 F6 06 3D -R 00 00 06 00 00 02 06 00 00 06 06 00 00 0D 06 00 -T F3 06 32 45 03 0E 01 CD 6B 06 CD 8C 05 C3 -R 00 00 06 00 00 03 06 00 00 08 06 00 00 0B 06 00 -T FF 06 D2 06 -R 00 00 06 00 00 02 06 00 -T 01 07 -R 00 00 06 00 -T 01 07 3A D4 0D C3 01 03 C5 F5 3A C5 0D 2F 47 79 -R 00 00 06 00 00 03 06 00 00 06 06 00 00 0B 06 00 -T 0F 07 A0 4F F1 A0 91 E6 1F C1 C9 3E FF 32 D4 0D -R 00 00 06 00 00 0E 06 00 -T 1D 07 21 D8 0D 71 2A 43 03 22 D9 0D CD -R 00 00 06 00 00 03 06 00 00 07 06 00 00 0A 06 00 -T 28 07 FE 05 CD A1 03 0E 00 CD 05 06 CD -R 00 00 06 00 00 02 06 00 00 05 06 00 00 0A 06 00 -T 33 07 F5 05 CA 94 07 2A D9 0D EB 1A FE E5 CA -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 40 07 4A 07 D5 CD 7F 05 D1 D2 94 07 CD -R 00 00 06 00 00 02 06 00 00 06 06 00 00 0A 06 00 -T 4B 07 5E 05 3A D8 0D 4F 06 00 79 B7 CA 83 07 1A -R 00 00 06 00 00 02 06 00 00 05 06 00 00 0D 06 00 -T 59 07 FE 3F CA 7C 07 78 FE 0D CA 7C 07 FE 0C 1A -R 00 00 06 00 00 05 06 00 00 0B 06 00 -T 67 07 CA 73 07 96 E6 7F C2 2D 07 C3 7C 07 C5 4E -R 00 00 06 00 00 03 06 00 00 09 06 00 00 0C 06 00 -T 75 07 CD 07 07 C1 C2 2D 07 13 23 04 0D C3 53 07 -R 00 00 06 00 00 03 06 00 00 07 06 00 00 0E 06 00 -T 83 07 3A EA 0D E6 03 32 45 03 21 D4 0D 7E 17 D0 -R 00 00 06 00 00 03 06 00 00 08 06 00 00 0B 06 00 -T 91 07 AF 77 C9 CD FE 05 3E FF C3 01 03 CD 54 05 -R 00 00 06 00 00 06 06 00 00 0B 06 00 00 0E 06 00 -T 9F 07 0E 0C CD 18 07 CD F5 05 C8 CD 44 05 CD -R 00 00 06 00 00 05 06 00 00 08 06 00 00 0C 06 00 -T AC 07 5E 05 36 E5 0E 00 CD 6B 06 CD C6 05 CD -R 00 00 06 00 00 02 06 00 00 09 06 00 00 0C 06 00 -T B9 07 2D 07 C3 A4 07 -R 00 00 06 00 00 02 06 00 00 05 06 00 -T BE 07 -R 00 00 06 00 -T BE 07 50 59 79 B0 CA D1 07 0B D5 C5 CD 35 06 1F -R 00 00 06 00 00 07 06 00 00 0D 06 00 -T CC 07 D2 EC 07 C1 D1 2A C6 0D 7B 95 7A 9C D2 -R 00 00 06 00 00 03 06 00 00 08 06 00 -T D9 07 F4 07 13 C5 D5 42 4B CD 35 06 1F D2 EC 07 -R 00 00 06 00 00 02 06 00 00 0A 06 00 00 0E 06 00 -T E7 07 D1 C1 C3 C0 07 17 3C CD 64 06 E1 D1 C9 79 -R 00 00 06 00 00 05 06 00 00 0A 06 00 -T F5 07 B0 C2 C0 07 21 00 00 C9 0E 00 1E 20 D5 06 -R 00 00 06 00 00 04 06 00 -T 03 08 00 2A 43 03 09 EB CD 5E 05 C1 CD 4F 03 CD -R 00 00 06 00 00 04 06 00 00 09 06 00 00 0D 06 00 -T 11 08 C3 03 C3 C6 05 -R 00 00 06 00 00 02 06 00 00 05 06 00 -T 16 08 -R 00 00 06 00 -T 16 08 CD 54 05 0E 0C CD 18 07 2A 43 03 7E 11 -R 00 00 06 00 00 03 06 00 00 08 06 00 00 0B 06 00 -T 23 08 10 00 19 77 CD F5 05 C8 CD 44 05 0E 10 1E -R 00 00 06 00 00 07 06 00 00 0B 06 00 -T 31 08 0C CD 01 08 CD 2D 07 C3 27 08 -R 00 00 06 00 00 04 06 00 00 07 06 00 00 0A 06 00 -T 3B 08 -R 00 00 06 00 -T 3B 08 0E 0C CD 18 07 CD F5 05 C8 0E 00 1E 0C CD -R 00 00 06 00 00 05 06 00 00 08 06 00 -T 49 08 01 08 CD 2D 07 C3 40 08 0E 0F CD -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 54 08 18 07 CD F5 05 C8 CD A6 04 7E F5 E5 CD -R 00 00 06 00 00 02 06 00 00 05 06 00 00 09 06 00 -T 61 08 5E 05 EB 2A 43 03 0E 20 D5 CD 4F 03 CD -R 00 00 06 00 00 02 06 00 00 06 06 00 00 0C 06 00 -T 6E 08 78 05 D1 21 0C 00 19 4E 21 0F 00 19 46 E1 -R 00 00 06 00 00 02 06 00 -T 7C 08 F1 77 79 BE 78 CA 8B 08 3E 00 DA 8B 08 3E -R 00 00 06 00 00 08 06 00 00 0D 06 00 -T 8A 08 80 2A 43 03 11 0F 00 19 77 C9 -R 00 00 06 00 00 04 06 00 -T 94 08 -R 00 00 06 00 -T 94 08 7E 23 B6 2B C0 1A 77 13 23 1A 77 1B 2B C9 -R 00 00 06 00 -T A2 08 AF 32 45 03 32 EA 0D 32 EB 0D CD -R 00 00 06 00 00 04 06 00 00 07 06 00 00 0A 06 00 -T AD 08 1E 05 C0 CD 69 05 E6 80 C0 0E 0F CD 18 07 -R 00 00 06 00 00 02 06 00 00 06 06 00 00 0E 06 00 -T BB 08 CD F5 05 C8 01 10 00 CD 5E 05 09 EB 2A -R 00 00 06 00 00 03 06 00 00 0A 06 00 -T C8 08 43 03 09 0E 10 -R 00 00 06 00 00 02 06 00 -T CD 08 -R 00 00 06 00 -T CD 08 3A DD 0D B7 CA E8 08 7E B7 1A C2 DB 08 77 -R 00 00 06 00 00 03 06 00 00 07 06 00 00 0D 06 00 -T DB 08 -R 00 00 06 00 -T DB 08 B7 C2 E1 08 7E 12 -R 00 00 06 00 00 04 06 00 -T E1 08 -R 00 00 06 00 -T E1 08 BE C2 1F 09 C3 FD 08 -R 00 00 06 00 00 04 06 00 00 07 06 00 -T E8 08 -R 00 00 06 00 -T E8 08 CD 94 08 EB CD 94 08 EB 1A BE C2 1F 09 13 -R 00 00 06 00 00 03 06 00 00 07 06 00 00 0D 06 00 -T F6 08 23 1A BE C2 1F 09 0D -R 00 00 06 00 00 06 06 00 -T FD 08 -R 00 00 06 00 -T FD 08 13 23 0D C2 CD 08 01 EC FF 09 EB 09 1A BE -R 00 00 06 00 00 06 06 00 -T 0B 09 DA 17 09 77 01 03 00 09 EB 09 7E 12 -R 00 00 06 00 00 03 06 00 -T 17 09 -R 00 00 06 00 -T 17 09 3E FF 32 D2 0D C3 10 08 -R 00 00 06 00 00 05 06 00 00 08 06 00 -T 1F 09 -R 00 00 06 00 -T 1F 09 21 45 03 35 C9 -R 00 00 06 00 00 03 06 00 -T 24 09 -R 00 00 06 00 -T 24 09 CD 54 05 2A 43 03 E5 21 AC 0D 22 -R 00 00 06 00 00 03 06 00 00 06 06 00 00 0A 06 00 -T 2F 09 43 03 0E 01 CD 18 07 CD F5 05 E1 22 -R 00 00 06 00 00 02 06 00 00 07 06 00 00 0A 06 00 -T 3B 09 43 03 C8 EB 21 0F 00 19 0E 11 AF 77 23 0D -R 00 00 06 00 00 02 06 00 -T 49 09 C2 46 09 21 0D 00 19 77 CD 8C 05 CD FD 07 -R 00 00 06 00 00 03 06 00 00 0B 06 00 00 0E 06 00 -T 57 09 C3 78 05 AF 32 D2 0D CD A2 08 CD -R 00 00 06 00 00 03 06 00 00 07 06 00 00 0A 06 00 -T 62 09 F5 05 C8 2A 43 03 01 0C 00 09 7E 3C E6 1F -R 00 00 06 00 00 02 06 00 00 06 06 00 -T 70 09 77 CA 83 09 47 3A C5 0D A0 21 D2 0D A6 CA -R 00 00 06 00 00 04 06 00 00 08 06 00 00 0C 06 00 -T 7E 09 8E 09 C3 AC 09 01 02 00 09 34 7E E6 0F CA -R 00 00 06 00 00 02 06 00 00 05 06 00 -T 8C 09 B6 09 0E 0F CD 18 07 CD F5 05 C2 -R 00 00 06 00 00 02 06 00 00 07 06 00 00 0A 06 00 -T 97 09 AC 09 3A D3 0D 3C CA B6 09 CD -R 00 00 06 00 00 02 06 00 00 05 06 00 00 09 06 00 -T A1 09 24 09 CD F5 05 CA B6 09 C3 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T AA 09 AF 09 CD 5A 08 CD BB 04 AF C3 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T B4 09 01 03 CD 05 03 C3 78 05 3E 01 32 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T BF 09 D5 0D 3E FF 32 D3 0D CD BB 04 3A -R 00 00 06 00 00 02 06 00 00 07 06 00 00 0A 06 00 -T CA 09 E3 0D 21 E1 0D BE DA E6 09 FE 80 C2 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 09 06 00 -T D6 09 FB 09 CD 5A 09 AF 32 E3 0D 3A -R 00 00 06 00 00 02 06 00 00 05 06 00 00 09 06 00 -T E0 09 45 03 B7 C2 FB 09 CD 77 04 CD -R 00 00 06 00 00 02 06 00 00 06 06 00 00 09 06 00 -T EA 09 84 04 CA FB 09 CD 8A 04 CD -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T F3 09 D1 03 CD B2 03 C3 D2 04 C3 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T FC 09 05 03 3E 01 32 D5 0D 3E 00 32 D3 0D CD -R 00 00 06 00 00 02 06 00 00 07 06 00 00 0C 06 00 -T 09 0A 54 05 2A 43 03 CD 47 05 CD -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 12 0A BB 04 3A E3 0D FE 80 D2 05 03 CD -R 00 00 06 00 00 02 06 00 00 05 06 00 00 0A 06 00 -T 1D 0A 77 04 CD 84 04 0E 00 C2 6E 0A CD -R 00 00 06 00 00 02 06 00 00 05 06 00 00 0A 06 00 -T 28 0A 3E 04 32 D7 0D 01 00 00 B7 CA 3B 0A 4F 0B -R 00 00 06 00 00 02 06 00 00 05 06 00 00 0C 06 00 -T 36 0A CD 5E 04 44 4D CD BE 07 7D B4 C2 48 0A 3E -R 00 00 06 00 00 03 06 00 00 08 06 00 00 0D 06 00 -T 44 0A 02 C3 01 03 22 E5 0D EB 2A 43 03 01 10 00 -R 00 00 06 00 00 04 06 00 00 07 06 00 00 0B 06 00 -T 52 0A 09 3A DD 0D B7 3A D7 0D CA 64 0A CD -R 00 00 06 00 00 04 06 00 00 08 06 00 00 0B 06 00 -T 5E 0A 64 05 73 C3 6C 0A 4F 06 00 09 09 73 23 72 -R 00 00 06 00 00 02 06 00 00 06 06 00 -T 6C 0A 0E 02 3A 45 03 B7 C0 C5 CD 8A 04 3A D5 0D -R 00 00 06 00 00 05 06 00 00 0B 06 00 00 0E 06 00 -T 7A 0A 3D 3D C2 BB 0A C1 C5 79 3D 3D C2 BB 0A E5 -R 00 00 06 00 00 05 06 00 00 0D 06 00 -T 88 0A 2A B9 0D 57 77 23 14 F2 8C 0A CD E0 05 2A -R 00 00 06 00 00 03 06 00 00 0A 06 00 00 0D 06 00 -T 96 0A E7 0D 0E 02 22 E5 0D C5 CD D1 03 C1 CD -R 00 00 06 00 00 02 06 00 00 07 06 00 00 0B 06 00 -T A3 0A B8 03 2A E5 0D 0E 00 3A C4 0D 47 A5 B8 23 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 0A 06 00 -T B1 0A C2 9A 0A E1 22 E5 0D CD DA 05 CD -R 00 00 06 00 00 03 06 00 00 07 06 00 00 0A 06 00 -T BC 0A D1 03 C1 C5 CD B8 03 C1 3A E3 0D 21 -R 00 00 06 00 00 02 06 00 00 07 06 00 00 0B 06 00 -T C8 0A E1 0D BE DA D2 0A 77 34 0E 02 00 00 21 -R 00 00 06 00 00 02 06 00 00 06 06 00 -T D5 0A 00 00 F5 CD 69 05 E6 7F 77 F1 FE 7F C2 -R 00 00 06 00 00 06 06 00 -T E2 0A 00 0B 3A D5 0D FE 01 C2 00 0B CD -R 00 00 06 00 00 02 06 00 00 05 06 00 00 0A 06 00 -T ED 0A D2 04 CD 5A 09 21 45 03 7E B7 C2 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T F8 0A FE 0A 3D 32 E3 0D 36 00 C3 D2 04 -R 00 00 06 00 00 02 06 00 00 06 06 00 00 0B 06 00 -T 03 0B -R 00 00 06 00 -T 03 0B AF 32 D5 0D C5 2A 43 03 EB 21 21 00 19 7E -R 00 00 06 00 00 04 06 00 00 08 06 00 -T 11 0B E6 7F F5 7E 17 23 7E 17 E6 1F 4F 7E 1F 1F -R 00 00 06 00 -T 1F 0B 1F 1F E6 0F 47 F1 23 6E 2C 2D 2E 06 C2 -R 00 00 06 00 -T 2C 0B 8B 0B 21 20 00 19 77 21 0C 00 19 79 96 C2 -R 00 00 06 00 00 02 06 00 -T 3A 0B 47 0B 21 0E 00 19 78 96 E6 7F CA 7F 0B C5 -R 00 00 06 00 00 02 06 00 00 0D 06 00 -T 48 0B D5 CD A2 08 D1 C1 2E 03 3A 45 03 3C CA -R 00 00 06 00 00 04 06 00 00 0B 06 00 -T 55 0B 84 0B 21 0C 00 19 71 21 0E 00 19 70 CD -R 00 00 06 00 00 02 06 00 -T 62 0B 51 08 3A 45 03 3C C2 7F 0B C1 C5 2E 04 0C -R 00 00 06 00 00 02 06 00 00 05 06 00 00 09 06 00 -T 70 0B CA 84 0B CD 24 09 2E 05 3A 45 03 3C CA -R 00 00 06 00 00 03 06 00 00 06 06 00 00 0B 06 00 -T 7D 0B 84 0B C1 AF C3 01 03 E5 CD 69 05 36 C0 E1 -R 00 00 06 00 00 02 06 00 00 07 06 00 00 0B 06 00 -T 8B 0B C1 7D 32 45 03 C3 78 05 0E FF CD 03 0B CC -R 00 00 06 00 00 05 06 00 00 08 06 00 00 0D 06 00 -T 99 0B C1 09 C9 -R 00 00 06 00 00 02 06 00 -T 9C 0B -R 00 00 06 00 -T 9C 0B 0E 00 CD 03 0B CC 03 0A C9 -R 00 00 06 00 00 05 06 00 00 08 06 00 -T A5 0B -R 00 00 06 00 -T A5 0B EB 19 4E 06 00 21 0C 00 19 7E 0F E6 80 81 -R 00 00 06 00 -T B3 0B 4F 3E 00 88 47 7E 0F E6 0F 80 47 21 0E 00 -R 00 00 06 00 -T C1 0B 19 7E 87 87 87 87 F5 80 47 F5 E1 7D E1 B5 -R 00 00 06 00 -T CF 0B E6 01 C9 0E 0C CD 18 07 2A 43 03 11 21 00 -R 00 00 06 00 00 08 06 00 00 0B 06 00 -T DD 0B 19 E5 72 23 72 23 72 CD F5 05 CA 0C 0C CD -R 00 00 06 00 00 0A 06 00 00 0D 06 00 -T EB 0B 5E 05 11 0F 00 CD A5 0B E1 E5 5F 79 96 23 -R 00 00 06 00 00 02 06 00 00 08 06 00 -T F9 0B 78 9E 23 7B 9E DA 06 0C 73 2B 70 2B 71 CD -R 00 00 06 00 00 08 06 00 -T 07 0C 2D 07 C3 E4 0B E1 C9 2A 43 03 11 20 00 CD -R 00 00 06 00 00 02 06 00 00 05 06 00 00 0A 06 00 -T 15 0C A5 0B 21 21 00 19 71 23 70 23 77 C9 -R 00 00 06 00 00 02 06 00 -T 21 0C -R 00 00 06 00 -T 21 0C 2A AF 0D 3A 42 03 4F CD EA 04 E5 EB CD -R 00 00 06 00 00 03 06 00 00 06 06 00 00 0A 06 00 -T 2E 0C 59 03 E1 CC 47 03 7D 1F D8 2A AF 0D 4D 44 -R 00 00 06 00 00 02 06 00 00 06 06 00 00 0C 06 00 -T 3C 0C CD 0B 05 22 AF 0D C3 A3 06 3A -R 00 00 06 00 00 03 06 00 00 06 06 00 00 09 06 00 -T 46 0C D6 0D 21 42 03 BE C8 77 C3 21 0C 3E FF 32 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 0B 06 00 -T 54 0C DE 0D 2A 43 03 7E E6 1F 3D 32 D6 0D FE 1E -R 00 00 06 00 00 02 06 00 00 05 06 00 00 0C 06 00 -T 62 0C D2 75 0C 3A 42 03 32 DF 0D 7E 32 -R 00 00 06 00 00 03 06 00 00 06 06 00 00 09 06 00 -T 6D 0C E0 0D E6 E0 77 CD 45 0C 3A 41 03 2A -R 00 00 06 00 00 02 06 00 00 08 06 00 00 0B 06 00 -T 79 0C 43 03 B6 77 C9 3E 22 C3 01 03 21 00 00 22 -R 00 00 06 00 00 02 06 00 00 0A 06 00 -T 87 0C AD 0D 22 AF 0D AF 32 42 03 21 80 00 22 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 09 06 00 -T 94 0C B1 0D CD DA 05 C3 21 0C CD -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 9D 0C 72 05 CD 51 0C C3 51 08 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T A5 0C -R 00 00 06 00 -T A5 0C CD 51 0C C3 A2 08 0E 00 EB 7E FE 3F CA -R 00 00 06 00 00 03 06 00 00 06 06 00 -T B2 0C C2 0C CD A6 04 7E FE 3F C4 72 05 CD -R 00 00 06 00 00 02 06 00 00 05 06 00 00 0B 06 00 -T BE 0C 51 0C 0E 0F CD 18 07 C3 E9 05 2A -R 00 00 06 00 00 02 06 00 00 07 06 00 00 0A 06 00 -T C9 0C D9 0D 22 43 03 CD 51 0C CD -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T D2 0C 2D 07 C3 E9 05 CD 51 0C CD -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T DB 0C 9C 07 C3 01 07 CD 51 0C C3 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T E4 0C BC 09 CD 51 0C C3 FE 09 CD -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T ED 0C 72 05 CD 51 0C C3 24 09 CD -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T F6 0C 51 0C CD 16 08 C3 01 07 2A -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T FF 0C AF 0D C3 29 0D 3A 42 03 C3 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 08 0D 01 03 EB 22 B1 0D C3 DA 05 2A -R 00 00 06 00 00 02 06 00 00 06 06 00 00 09 06 00 -T 12 0D BF 0D C3 29 0D 2A AD 0D C3 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 1B 0D 29 0D CD 51 0C CD 3B 08 C3 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 24 0D 01 07 2A BB 0D 22 45 03 C9 3A -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 2E 0D D6 0D FE FF C2 3B 0D 3A 41 03 C3 -R 00 00 06 00 00 02 06 00 00 07 06 00 00 0A 06 00 -T 39 0D 01 03 E6 1F 32 41 03 C9 -R 00 00 06 00 00 02 06 00 00 07 06 00 -T 41 0D -R 00 00 06 00 -T 41 0D CD 51 0C C3 93 0B -R 00 00 06 00 00 03 06 00 00 06 06 00 -T 47 0D -R 00 00 06 00 -T 47 0D CD 51 0C C3 9C 0B -R 00 00 06 00 00 03 06 00 00 06 06 00 -T 4D 0D -R 00 00 06 00 -T 4D 0D CD 51 0C C3 D2 0B 2A 43 03 7D 2F 5F 7C 2F -R 00 00 06 00 00 03 06 00 00 06 06 00 00 09 06 00 -T 5B 0D 2A AF 0D A4 57 7D A3 5F 2A AD 0D EB 22 -R 00 00 06 00 00 03 06 00 00 0B 06 00 -T 68 0D AF 0D 7D A3 6F 7C A2 67 22 AD 0D C9 3A -R 00 00 06 00 00 02 06 00 00 0B 06 00 -T 75 0D DE 0D B7 CA 91 0D 2A 43 03 36 00 3A -R 00 00 06 00 00 02 06 00 00 06 06 00 00 09 06 00 -T 81 0D E0 0D B7 CA 91 0D 77 3A DF 0D 32 -R 00 00 06 00 00 02 06 00 00 06 06 00 00 0A 06 00 -T 8C 0D D6 0D CD 45 0C 2A 0F 03 F9 2A -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 96 0D 45 03 7D 44 C9 CD 51 0C 3E 02 32 D5 0D 0E -R 00 00 06 00 00 02 06 00 00 08 06 00 00 0D 06 00 -T A4 0D 00 CD 07 0B CC 03 0A C9 -R 00 00 06 00 00 04 06 00 00 07 06 00 -T AC 0D -R 00 00 06 00 -T AC 0D E5 00 00 00 00 80 00 -R 00 00 06 00 -T B3 0D -R 00 00 06 00 -T B3 0D 00 00 -R 00 00 06 00 -T B5 0D -R 00 00 06 00 -T B5 0D 00 00 -R 00 00 06 00 -T B7 0D -R 00 00 06 00 -T B7 0D 00 00 00 00 00 00 00 00 -R 00 00 06 00 -T BF 0D -R 00 00 06 00 -T BF 0D 00 00 00 00 00 00 00 00 00 00 00 00 00 -R 00 00 06 00 -T CC 0D 00 00 00 00 00 00 -R 00 00 06 00 -T D2 0D -R 00 00 06 00 -T D2 0D 00 -R 00 00 06 00 -T D3 0D -R 00 00 06 00 -T D3 0D 00 00 00 00 -R 00 00 06 00 -T D7 0D -R 00 00 06 00 -T D7 0D 00 00 00 00 00 00 00 00 00 -R 00 00 06 00 -T E0 0D -R 00 00 06 00 -T E0 0D 00 00 00 00 00 00 00 00 00 00 00 00 -R 00 00 06 00 -T EC 0D -R 00 00 06 00 -T EC 0D 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -R 00 00 06 00 -T FA 0D 00 00 -R 00 00 06 00 -T FC 0D -R 00 00 06 00 diff --git a/doug/src/bdosb01.s b/doug/src/bdosb01.s deleted file mode 100755 index 70328e01..00000000 --- a/doug/src/bdosb01.s +++ /dev/null @@ -1,2654 +0,0 @@ - .title bdosb01.s derived from bdosb01.asm - .sbttl by Douglas Goodall for N8VEM use '11 - - .module bdosb01 - .optsdcc -mz80 - -;-------------------------------------------------------- -; Public variables in this module -;-------------------------------------------------------- - .globl _bdos -;-------------------------------------------------------- -; special function registers -;-------------------------------------------------------- -;-------------------------------------------------------- -; ram data -;-------------------------------------------------------- - .area _DATA -;-------------------------------------------------------- -; overlayable items in ram -;-------------------------------------------------------- - .area _OVERLAY -;-------------------------------------------------------- -; external initialized ram data -;-------------------------------------------------------- -;-------------------------------------------------------- -; global & static initialisations -;-------------------------------------------------------- - .area _HOME - .area _GSINIT - .area _GSFINAL - .area _GSINIT -;-------------------------------------------------------- -; Home -;-------------------------------------------------------- - .area _HOME - .area _HOME -;-------------------------------------------------------- -; code -;-------------------------------------------------------- - .area _CODE -;bdos.c:1: void bdos(void) -; --------------------------------- -; Function bdos -; --------------------------------- -_bdos_start:: -_bdos: - -;dwg-start; - .area _DATA -;dwg-end; - -ENDFIL = 1 ;FILL FULL BDOS LENGTH -; -IOBYTE = 3 ; I/O DEFINITION BYTE. -TDRIVE = 4 ; CURRENT DRIVE NAME AND USER NUMBER. -ENTRY = 5 ; ENTRY POINT FOR THE CP/M BDOS. -TFCB = 0x5C ; DEFAULT FILE CONTROL BLOCK. -TBUFF = 0x80 ; I/O BUFFER AND COMMAND LINE STORAGE. -TBASE = 0x100 ; TRANSIANT PROGRAM STORAGE AREA. -; -; SET CONTROL CHARACTER .EQUATES. -; -ASCIIA = 0x41 -AT = 0x40 -CNTRLC = 3 ; CONTROL-C -CNTRLE = 05 ; CONTROL-E -BS = 08 ; BACKSPACE -TAB = 09 ; TAB -LF = 0x0A ; LINE FEED -FF = 0x0C ; FORM FEED -CR = 0x0D ; CARRIAGE RETURN -CNTRLP = 0x10 ; CONTROL-P -CNTRLR = 0x12 ; CONTROL-R -CNTRLS = 0x13 ; CONTROL-S -CNTRLU = 0x15 ; CONTROL-U -CNTRLX = 0x18 ; CONTROL-X -CNTRLZ = 0x1A ; CONTROL-Z (END-OF-FILE MARK) -SPACE = 0x20 -POUND = 0x23 -DOLLAR = 0x24 -QUESTION = 0x3f -UP = 0x5E -DEL = 0x7F ; RUBOUT - -; CPM ORIGIN CALCULATE - -NK = 59 ;SYSTEM SIZE -BASE = (NK*1024)-0x5000 -CCPO = BASE+0x3400 ;CCP ORIGIN -BDOSO = BASE+0x3C00 ;BDOS ORIGIN -BIOSO = BASE+0x4A00 ;BIOS ORIGIN - -;dwg-begin; - -; .area _CODE - .area _BDOSB01 - -;dwg-end; - -;dwg; .ORG BDOSO - .DB 0,0,0,0,0,0 ;OLD SERIAL NUMBER -; -;************************************************************** -;* -;* B D O S E N T R Y -;* -;************************************************************** -; -FBASE: JP FBASE1 -; -; BDOS ERROR TABLE. -; -BADSCTR:.DW ERROR1 ; BAD SECTOR ON READ OR WRITE. -BADSLCT:.DW ERROR2 ; BAD DISK SELECT. -RODISK: .DW ERROR3 ; DISK IS READ ONLY. -ROFILE: .DW ERROR4 ; FILE IS READ ONLY. -; -; ENTRY INTO BDOS. (DE) OR (E) ARE THE PARAMETERS PASSED. THE -; FUNCTION NUMBER DESIRED IS IN REGISTER (C). -; E contains drive number if passing this -FBASE1: EX DE,HL ; SAVE THE (DE) PARAMETERS. - LD (PARAMS),HL - EX DE,HL - LD A,E ; AND SAVE REGISTER (E) IN PARTICULAR. - LD (EPARAM),A - LD HL,#0 - LD (STATUS),HL ; CLEAR RETURN STATUS. - ADD HL,SP - LD (USRSTACK),HL ; SAVE USERS STACK POINTER. - LD SP,#STKAREA ; AND SET OUR OWN. - XOR A ; CLEAR AUTO SELECT STORAGE SPACE. - LD (AUTOFLAG),A - LD (AUTO),A - LD HL,#GOBACK ; SET RETURN ADDRESS. - PUSH HL - LD A,C ; GET FUNCTION NUMBER. - CP #NFUNCTS ; VALID FUNCTION NUMBER? - RET NC - LD C,E ; KEEP SINGLE REGISTER FUNCTION HERE. - LD HL,#FUNCTNS ; NOW LOOK THRU THE FUNCTION TABLE. - LD E,A - LD D,#0 ; (DE)=FUNCTION NUMBER. - ADD HL,DE - ADD HL,DE ; (HL)=(START OF TABLE)+2*(FUNCTION NUMBER). - LD E,(HL) - INC HL - LD D,(HL) ; NOW (DE)=ADDRESS FOR THIS FUNCTION. - LD HL,(PARAMS) ; RETRIEVE PARAMETERS. - EX DE,HL ; NOW (DE) HAS THE ORIGINAL PARAMETERS. - JP (HL) ; EXECUTE DESIRED FUNCTION. -; -; BDOS FUNCTION JUMP TABLE. -; -NFUNCTS = 41 ; NUMBER OF FUNCTIONS IN FOLLOWIN TABLE. -; -FUNCTNS:.DW WBOOT,GETCON,OUTCON,GETRDR,PUNCH,LIST,DIRCIO,GETIOB - .DW SETIOB,PRTSTR,R.DBUFF,GETCSTS,GETVER,RSTDSK,SETDSK,OPENFIL - .DW CLOSEFIL,GETFST,GETNXT,DELFILE,READSEQ,WRTSEQ,FCREATE - .DW RENFILE,GETLOG,GETCRNT,PUTDMA,GETALOC,WRTPRTD,GETROV,SETATTR - .DW GETPARM,GETUSER,RDRANDOM,WTRANDOM,FILESIZE,SETRAN,LOGOFF,RTN - .DW RTN,WTSPECL -; -; BDOS ERROR MESSAGE SECTION. -; -ERROR1: LD HL,#BADSEC ; BAD SECTOR MESSAGE. - CALL PRTERR ; PRINT IT AND GET A 1 CHAR RESPONCE. - CP #CNTRLC ; RE-BOOT R.EQUEST (CONTROL-C)? - JP Z,0 ; YES. - RET ; NO, RETURN TO RETRY I/O FUNCTION. -; -ERROR2: LD HL,#BADSEL ; BAD DRIVE SELECTED. - JP ERROR5 -; -ERROR3: LD HL,#DISKRO ; DISK IS READ ONLY. - JP ERROR5 -; -ERROR4: LD HL,#FILERO ; FILE IS READ ONLY. -; -ERROR5: CALL PRTERR - JP 0 ; ALWAYS REBOOT ON THESE ERRORS. -; -BDOSERR: .ascii "BDOS ERR ON " -BDOSDRV: .ascii " : $" -BADSEC: .ascii "BAD SECTOR$" -BADSEL: .ascii "SELECT$" -FILERO: .ascii "FILE " -DISKRO: .ascii "R/O$" -; -; PRINT BDOS ERROR MESSAGE. -; -PRTERR: PUSH HL ; SAVE SECOND MESSAGE POINTER. - CALL OUTCRLF ; SEND (CR)(LF). - LD A,(ACTIVE) ; GET ACTIVE DRIVE. - ADD A,#ASCIIA ; MAKE ASCII. - LD (BDOSDRV),A ; AND PUT IN MESSAGE. - LD BC,#BDOSERR ; AND PRINT IT. - CALL PRTMESG - POP BC ; PRINT SECOND MESSAGE LINE NOW. - CALL PRTMESG -; -; GET AN INPUT CHARACTER. WE WILL CHECK OUR 1 CHARACTER -; BUFFER FIRST. THIS MAY BE SET BY THE CONSOLE STATUS ROUTINE. -; -GETCHAR:LD HL,#CHARBUF ; CHECK CHARACTER BUFFER. - LD A,(HL) ; ANYTHING PRESENT ALREADY? - LD (HL),#0 ; ...EITHER CASE CLEAR IT. - OR A - RET NZ ; YES, USE IT. - JP CONIN ; NOPE, GO GET A CHARACTER RESPONCE. -; -; INPUT AND ECHO A CHARACTER. -; -GETECHO:CALL GETCHAR ; INPUT A CHARACTER. - CALL CHKCHAR ; CARRIAGE CONTROL? - RET C ; NO, A REGULAR CONTROL CHAR SO DON'T ECHO. - PUSH AF ; OK, SAVE CHARACTER NOW. - LD C,A - CALL OUTCON ; AND ECHO IT. - POP AF ; GET CHARACTER AND RETURN. - RET -; -; CHECK CHARACTER IN (A). SET THE ZERO FLAG ON A CARRIAGE -; CONTROL CHARACTER AND THE CARRY FLAG ON ANY OTHER CONTROL -; CHARACTER. -; -CHKCHAR:CP #CR ; CHECK FOR CARRIAGE RETURN, LINE FEED, BACKSPACE, - RET Z ; OR A TAB. - CP #LF - RET Z - CP #TAB - RET Z - CP #BS - RET Z - CP #SPACE ; OTHER CONTROL CHAR? SET CARRY FLAG. - RET -; -; CHECK THE CONSOLE DURING OUTPUT. HALT ON A CONTROL-S, THEN -; REBOOT ON A CONTROL-C. IF ANYTHING ELSE IS READY, CLEAR THE -; ZERO FLAG AND RETURN (THE CALLING ROUTINE MAY WANT TO DO -; SOMETHING). -; -CKCONSOL: - LD A,(CHARBUF) ; CHECK BUFFER. - OR A ; IF ANYTHING, JUST RETURN WITHOUT CHECKING. - JP NZ,CKCON2 - CALL CONST ; NOTHING IN BUFFER. CHECK CONSOLE. - AND #0x01 ; LOOK AT BIT 0. - RET Z ; RETURN IF NOTHING. - CALL CONIN ; OK, GET IT. - CP #CNTRLS ; IF NOT CONTROL-S, RETURN WITH ZERO CLEARED. - JP NZ,CKCON1 - CALL CONIN ; HALT PROCESSING UNTIL ANOTHER CHAR - CP #CNTRLC ; IS TYPED. CONTROL-C? - JP Z,0 ; YES, REBOOT NOW. - XOR A ; NO, JUST PRETEND NOTHING WAS EVER READY. - RET -CKCON1: LD (CHARBUF),A ; SAVE CHARACTER IN BUFFER FOR LATER PROCESSING. -CKCON2: LD A,#1 ; SET (A) TO NON ZERO TO MEAN SOMETHING IS READY. - RET -; -; OUTPUT (C) TO THE SCREEN. IF THE PRINTER FLIP-FLOP FLAG -; IS SET, WE WILL SEND CHARACTER TO PRINTER ALSO. THE CONSOLE -; WILL BE CHECKED IN THE PROCESS. -; -OUTCHAR:LD A,(OUTFLAG) ; CHECK OUTPUT FLAG. - OR A ; ANYTHING AND WE WON'T GENERATE OUTPUT. - JP NZ,OUTCHR1 - PUSH BC - CALL CKCONSOL ; CHECK CONSOLE (WE DON'T CARE WHATS THERE). - POP BC - PUSH BC - CALL CONOUT ; OUTPUT (C) TO THE SCREEN. - POP BC - PUSH BC - LD A,(PRTFLAG) ; CHECK PRINTER FLIP-FLOP FLAG. - OR A - CALL NZ,LIST ; PRINT IT ALSO IF NON-ZERO. - POP BC -OUTCHR1:LD A,C ; UPDATE CURSORS POSITION. - LD HL,#CURPOS - CP #DEL ; RUBOUTS DON'T DO ANYTHING HERE. - RET Z - INC (HL) ; BUMP LINE POINTER. - CP #SPACE ; AND RETURN IF A NORMAL CHARACTER. - RET NC - DEC (HL) ; RESTORE AND CHECK FOR THE START OF THE LINE. - LD A,(HL) - OR A - RET Z ; INGNORE CONTROL CHARACTERS AT THE START OF THE LINE. - LD A,C - CP #BS ; IS IT A BACKSPACE? - JP NZ,OUTCHR2 - DEC (HL) ; YES, BACKUP POINTER. - RET -OUTCHR2:CP #LF ; IS IT A LINE FEED? - RET NZ ; IGNORE ANYTHING ELSE. - LD (HL),#0 ; RESET POINTER TO START OF LINE. - RET -; -; OUTPUT (A) TO THE SCREEN. IF IT IS A CONTROL CHARACTER -; (OTHER THAN CARRIAGE CONTROL), USE ^X FORMAT. -; -SHOWIT: LD A,C - CALL CHKCHAR ; CHECK CHARACTER. - JP NC,OUTCON ; NOT A CONTROL, USE NORMAL OUTPUT. - PUSH AF - LD C,#UP ; FOR A CONTROL CHARACTER, PRECEED IT WITH '^'. - CALL OUTCHAR - POP AF - OR #AT ; AND THEN USE THE LETTER .EQUIVELANT. - LD C,A -; -; FUNCTION TO OUTPUT (C) TO THE CONSOLE DEVICE AND EXPAND TABS -; IF NECESSARY. -; -OUTCON: LD A,C - CP #TAB ; IS IT A TAB? - JP NZ,OUTCHAR ; USE REGULAR OUTPUT. -OUTCON1:LD C,#SPACE ; YES IT IS, USE SPACES INSTEAD. - CALL OUTCHAR - LD A,(CURPOS) ; GO UNTIL THE CURSOR IS AT A MULTIPLE OF 8 - - AND #7 ; POSITION. - JP NZ,OUTCON1 - RET -; -; ECHO A BACKSPACE CHARACTER. ERASE THE PREVOIUS CHARACTER -; ON THE SCREEN. -; -BACKUP: CALL BACKUP1 ; BACKUP THE SCREEN 1 PLACE. - LD C,#SPACE ; THEN BLANK THAT CHARACTER. - CALL CONOUT -BACKUP1:LD C,#BS ; THEN BACK SPACE ONCE MORE. - JP CONOUT -; -; SIGNAL A DELETED LINE. PRINT A '#' AT THE END AND START -; OVER. -; -NEWLINE:LD C,#POUND - CALL OUTCHAR ; PRINT THIS. - CALL OUTCRLF ; START NEW LINE. -NEWLN1: LD A,(CURPOS) ; MOVE THE CURSOR TO THE STARTING POSITION. - LD HL,#STARTING - CP (HL) - RET NC ; THERE YET? - LD C,#SPACE - CALL OUTCHAR ; NOPE, KEEP GOING. - JP NEWLN1 -; -; OUTPUT A (CR) (LF) TO THE CONSOLE DEVICE (SCREEN). -; -OUTCRLF:LD C,#CR - CALL OUTCHAR - LD C,#LF - JP OUTCHAR -; -; PRINT MESSAGE POINTED TO BY (BC). IT WILL END WITH A '$'. -; -PRTMESG:LD A,(BC) ; CHECK FOR TERMINATING CHARACTER. - CP #DOLLAR - RET Z - INC BC - PUSH BC ; OTHERWISE, BUMP POINTER AND PRINT IT. - LD C,A - CALL OUTCON - POP BC - JP PRTMESG -; -; FUNCTION TO EXECUTE A BUFFERED READ. -; -R.DBUFF: LD A,(CURPOS) ; USE PRESENT LOCATION AS STARTING ONE. - LD (STARTING),A - LD HL,(PARAMS) ; GET THE MAXIMUM BUFFER SPACE. - LD C,(HL) - INC HL ; POINT TO FIRST AVAILABLE SPACE. - PUSH HL ; AND SAVE. - LD B,#0 ; KEEP A CHARACTER COUNT. -R.DBUF1: PUSH BC - PUSH HL -R.DBUF2: CALL GETCHAR ; GET THE NEXT INPUT CHARACTER. - AND #0x7F ; STRIP BIT 7. - POP HL ; RESET REGISTERS. - POP BC - CP #CR ; EN OF THE LINE? - JP Z,R.DBUF17 - CP #LF - JP Z,R.DBUF17 - CP #BS ; HOW ABOUT A BACKSPACE? - JP NZ,R.DBUF3 - LD A,B ; YES, BUT IGNORE AT THE BEGINNING OF THE LINE. - OR A - JP Z,R.DBUF1 - DEC B ; OK, UPDATE COUNTER. - LD A,(CURPOS) ; IF WE BACKSPACE TO THE START OF THE LINE, - LD (OUTFLAG),A ; TREAT AS A CANCEL (CONTROL-X). - JP R.DBUF10 -R.DBUF3: CP #DEL ; USER TYPED A RUBOUT? - JP NZ,R.DBUF4 - LD A,B ; IGNORE AT THE START OF THE LINE. - OR A - JP Z,R.DBUF1 - LD A,(HL) ; OK, ECHO THE PREVOIUS CHARACTER. - DEC B ; AND RESET POINTERS (COUNTERS). - DEC HL - JP R.DBUF15 -R.DBUF4: CP #CNTRLE ; PHYSICAL END OF LINE? - JP NZ,R.DBUF5 - PUSH BC ; YES, DO IT. - PUSH HL - CALL OUTCRLF - XOR A ; AND UPDATE STARTING POSITION. - LD (STARTING),A - JP R.DBUF2 -R.DBUF5: CP #CNTRLP ; CONTROL-P? - JP NZ,R.DBUF6 - PUSH HL ; YES, FLIP THE PRINT FLAG FILP-FLOP BYTE. - LD HL,#PRTFLAG - LD A,#1 ; PRTFLAG=1-PRTFLAG - SUB (HL) - LD (HL),A - POP HL - JP R.DBUF1 -R.DBUF6: CP #CNTRLX ; CONTROL-X (CANCEL)? - JP NZ,R.DBUF8 - POP HL -R.DBUF7: LD A,(STARTING) ; YES, BACKUP THE CURSOR TO HERE. - LD HL,#CURPOS - CP (HL) - JP NC,R.DBUFF ; DONE YET? - DEC (HL) ; NO, DECREMENT POINTER AND OUTPUT BACK UP ONE SPACE. - CALL BACKUP - JP R.DBUF7 -R.DBUF8: CP #CNTRLU ; CNTROL-U (CANCEL LINE)? - JP NZ,R.DBUF9 - CALL NEWLINE ; START A NEW LINE. - POP HL - JP R.DBUFF -R.DBUF9: CP #CNTRLR ; CONTROL-R? - JP NZ,R.DBUF14 -R.DBUF10:PUSH BC ; YES, START A NEW LINE AND RETYPE THE OLD ONE. - CALL NEWLINE - POP BC - POP HL - PUSH HL - PUSH BC -R.DBUF11:LD A,B ; DONE WHOLE LINE YET? - OR A - JP Z,R.DBUF12 - INC HL ; NOPE, GET NEXT CHARACTER. - LD C,(HL) - DEC B ; COUNT IT. - PUSH BC - PUSH HL - CALL SHOWIT ; AND DISPLAY IT. - POP HL - POP BC - JP R.DBUF11 -R.DBUF12:PUSH HL ; DONE WITH LINE. IF WE WERE DISPLAYING - LD A,(OUTFLAG) ; THEN UPDATE CURSOR POSITION. - OR A - JP Z,R.DBUF2 - LD HL,#CURPOS ; BECAUSE THIS LINE IS SHORTER, WE MUST - SUB (HL) ; BACK UP THE CURSOR (NOT THE SCREEN HOWEVER) - LD (OUTFLAG),A ; SOME NUMBER OF POSITIONS. -R.DBUF13:CALL BACKUP ; NOTE THAT AS LONG AS (OUTFLAG) IS NON - LD HL,#OUTFLAG ; ZERO, THE SCREEN WILL NOT BE CHANGED. - DEC (HL) - JP NZ,R.DBUF13 - JP R.DBUF2 ; NOW JUST GET THE NEXT CHARACTER. -; -; JUST A NORMAL CHARACTER, PUT THIS IN OUR BUFFER AND ECHO. -; -R.DBUF14:INC HL - LD (HL),A ; STORE CHARACTER. - INC B ; AND COUNT IT. -R.DBUF15:PUSH BC - PUSH HL - LD C,A ; ECHO IT NOW. - CALL SHOWIT - POP HL - POP BC - LD A,(HL) ; WAS IT AN ABORT R.EQUEST? - CP #CNTRLC ; CONTROL-C ABORT? - LD A,B - JP NZ,R.DBUF16 - CP #1 ; ONLY IF AT START OF LINE. - JP Z,0 -R.DBUF16:CP C ; NOPE, HAVE WE FILLED THE BUFFER? - JP C,R.DBUF1 -R.DBUF17:POP HL ; YES END THE LINE AND RETURN. - LD (HL),B - LD C,#CR - JP OUTCHAR ; OUTPUT (CR) AND RETURN. -; -; FUNCTION TO GET A CHARACTER FROM THE CONSOLE DEVICE. -; -GETCON: CALL GETECHO ; GET AND ECHO. - JP SETSTAT ; SAVE STATUS AND RETURN. -; -; FUNCTION TO GET A CHARACTER FROM THE TAPE READER DEVICE. -; -GETRDR: CALL READER ; GET A CHARACTER FROM READER, SET STATUS AND RETURN. - JP SETSTAT -; -; FUNCTION TO PERFORM DIRECT CONSOLE I/O. IF (C) CONTAINS (FF) -; THEN THIS IS AN INPUT R.EQUEST. IF (C) CONTAINS (FE) THEN -; THIS IS A STATUS R.EQUEST. OTHERWISE WE ARE TO OUTPUT (C). -; -DIRCIO: LD A,C ; TEST FOR (FF). - INC A - JP Z,DIRC1 - INC A ; TEST FOR (FE). - JP Z,CONST - JP CONOUT ; JUST OUTPUT (C). -DIRC1: CALL CONST ; THIS IS AN INPUT R.EQUEST. - OR A - JP Z,GOBACK1 ; NOT READY? JUST RETURN (DIRECTLY). - CALL CONIN ; YES, GET CHARACTER. - JP SETSTAT ; SET STATUS AND RETURN. -; -; FUNCTION TO RETURN THE I/O BYTE. -; -GETIOB: LD A,(IOBYTE) - JP SETSTAT -; -; FUNCTION TO SET THE I/O BYTE. -; -SETIOB: LD HL,#IOBYTE - LD (HL),C - RET -; -; FUNCTION TO PRINT THE CHARACTER STRING POINTED TO BY (DE) -; ON THE CONSOLE DEVICE. THE STRING ENDS WITH A '$'. -; -PRTSTR: EX DE,HL - LD C,L - LD B,H ; NOW (BC) POINTS TO IT. - JP PRTMESG -; -; FUNCTION TO INTERIGATE THE CONSOLE DEVICE. -; -GETCSTS:CALL CKCONSOL -; -; GET HERE TO SET THE STATUS AND RETURN TO THE CLEANUP -; SECTION. THEN BACK TO THE USER. -; -SETSTAT:LD (STATUS),A -RTN: RET -; -; SET THE STATUS TO 1 (READ OR WRITE ERROR CODE). -; -IOERR1: LD A,#1 - JP SETSTAT -; -OUTFLAG:.DB 0 ; OUTPUT FLAG (NON ZERO MEANS NO OUTPUT). -STARTING: - .DB 2 ; STARTING POSITION FOR CURSOR. -CURPOS: .DB 0 ; CURSOR POSITION (0=START OF LINE). -PRTFLAG:.DB 0 ; PRINTER FLAG (CONTROL-P TOGGLE). LIST IF NON ZERO. -CHARBUF:.DB 0 ; SINGLE INPUT CHARACTER BUFFER. -; -; STACK AREA FOR BDOS CALLS. -; -USRSTACK: - .DW 0 ; SAVE USERS STACK POINTER HERE. -; - .DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -STKAREA: ; END OF STACK AREA. -; -USERNO: .DB 0 ; CURRENT USER NUMBER. -ACTIVE: .DB 0 ; CURRENTLY ACTIVE DRIVE. -PARAMS: .DW 0 ; SAVE (DE) PARAMETERS HERE ON ENTRY. -STATUS: .DW 0 ; STATUS RETURNED FROM BDOS FUNCTION. -; -; SELECT ERROR OCCURED, JUMP TO ERROR ROUTINE. -; -SLCTERR:LD HL,#BADSLCT -; -; JUMP TO (HL) INDIRECTLY. -; -JUMPHL: LD E,(HL) - INC HL - LD D,(HL) ; NOW (DE) CONTAIN THE DESIRED ADDRESS. - EX DE,HL - JP (HL) -; -; BLOCK MOVE. (DE) TO (HL), (C) BYTES TOTAL. -; -DE2HL: INC C ; IS COUNT DOWN TO ZERO? -DE2HL1: DEC C - RET Z ; YES, WE ARE DONE. - LD A,(DE) ; NO, MOVE ONE MORE BYTE. - LD (HL),A - INC DE - INC HL - JP DE2HL1 ; AND REPEAT. -; -; SELECT THE DESIRED DRIVE. -; -SELECT: LD A,(ACTIVE) ; GET ACTIVE DISK. - LD C,A - CALL SELDSK ; SELECT IT. - LD A,H ; VALID DRIVE? - OR L ; VALID DRIVE? - RET Z ; RETURN IF NOT. -; -; HERE, THE BIOS RETURNED THE ADDRESS OF THE PARAMETER BLOCK -; IN (HL). WE WILL EXTRACT THE NECESSARY POINTERS AND SAVE THEM. -; - LD E,(HL) ; YES, GET ADDRESS OF TRANSLATION TABLE INTO (DE). - INC HL - LD D,(HL) - INC HL - LD (SCRATCH1),HL ; SAVE POINTERS TO SCRATCH AREAS. - INC HL - INC HL - LD (SCRATCH2),HL ; DITTO. - INC HL - INC HL - LD (SCRATCH3),HL ; DITTO. - INC HL - INC HL - EX DE,HL ; NOW SAVE THE TRANSLATION TABLE ADDRESS. - LD (XLATE),HL - LD HL,#DIRBUF ; PUT THE NEXT 8 BYTES HERE. - LD C,#8 ; THEY CONSIST OF THE DIRECTORY BUFFER - CALL DE2HL ; POINTER, PARAMETER BLOCK POINTER, - LD HL,(DISKPB) ; CHECK AND ALLOCATION VECTORS. - EX DE,HL - LD HL,#SECTORS ; MOVE PARAMETER BLOCK INTO OUR RAM. - LD C,#15 ; IT IS 15 BYTES LONG. - CALL DE2HL - LD HL,(DSKSIZE) ; CHECK DISK SIZE. - LD A,H ; MORE THAN 256 BLOCKS ON THIS? - LD HL,#BIGDISK - LD (HL),#0x0FF ; SET TO SAMLL. - OR A - JP Z,SELECT1 - LD (HL),#0 ; WRONG, SET TO LARGE. -SELECT1:LD A,#0x0FF ; CLEAR THE ZERO FLAG. - OR A - RET -; -; ROUTINE TO HOME THE DISK TRACK HEAD AND CLEAR POINTERS. -; -HOMEDRV:CALL HOME ; HOME THE HEAD. - XOR A - LD HL,(SCRATCH2) ; SET OUR TRACK POINTER ALSO. - LD (HL),A - INC HL - LD (HL),A - LD HL,(SCRATCH3) ; AND OUR SECTOR POINTER. - LD (HL),A - INC HL - LD (HL),A - RET -; -; DO THE ACTUAL DISK READ AND CHECK THE ERROR RETURN STATUS. -; -DOREAD: CALL READ - JP IORET -; -; DO THE ACTUAL DISK WRITE AND HANDLE ANY BIOS ERROR. -; -DOWRITE:CALL WRITE -IORET: OR A - RET Z ; RETURN UNLESS AN ERROR OCCURED. - LD HL,#BADSCTR ; BAD READ/WRITE ON THIS SECTOR. - JP JUMPHL -; -; ROUTINE TO SELECT THE TRACK AND SECTOR THAT THE DESIRED -; BLOCK NUMBER FALLS IN. -; -TRKSEC: LD HL,(FILEPOS) ; GET POSITION OF LAST ACCESSED FILE - LD C,#2 ; IN DIRECTORY AND COMPUTE SECTOR #. - CALL SHIFTR ; SECTOR #=FILE-POSITION/4. - LD (BLKNMBR),HL ; SAVE THIS AS THE BLOCK NUMBER OF INTEREST. - LD (CKSUMTBL),HL ; WHAT'S IT DOING HERE TOO? -; -; IF THE SECTOR NUMBER HAS ALREADY BEEN SET (BLKNMBR), ENTER -; AT THIS POINT. -; -TRKSEC1:LD HL,#BLKNMBR - LD C,(HL) ; MOVE SECTOR NUMBER INTO (BC). - INC HL - LD B,(HL) - LD HL,(SCRATCH3) ; GET CURRENT SECTOR NUMBER AND - LD E,(HL) ; MOVE THIS INTO (DE). - INC HL - LD D,(HL) - LD HL,(SCRATCH2) ; GET CURRENT TRACK NUMBER. - LD A,(HL) ; AND THIS INTO (HL). - INC HL - LD H,(HL) - LD L,A -TRKSEC2:LD A,C ; IS DESIRED SECTOR BEFORE CURRENT ONE? - SUB E - LD A,B - SBC A,D - JP NC,TRKSEC3 - PUSH HL ; YES, DECREMENT SECTORS BY ONE TRACK. - LD HL,(SECTORS) ; GET SECTORS PER TRACK. - LD A,E - SUB L - LD E,A - LD A,D - SBC A,H - LD D,A ; NOW WE HAVE BACKED UP ONE FULL TRACK. - POP HL - DEC HL ; ADJUST TRACK COUNTER. - JP TRKSEC2 -TRKSEC3:PUSH HL ; DESIRED SECTOR IS AFTER CURRENT ONE. - LD HL,(SECTORS) ; GET SECTORS PER TRACK. - ADD HL,DE ; BUMP SECTOR POINTER TO NEXT TRACK. - JP C,TRKSEC4 - LD A,C ; IS DESIRED SECTOR NOW BEFORE CURRENT ONE? - SUB L - LD A,B - SBC A,H - JP C,TRKSEC4 - EX DE,HL ; NOT YES, INCREMENT TRACK COUNTER - POP HL ; AND CONTINUE UNTIL IT IS. - INC HL - JP TRKSEC3 -; -; HERE WE HAVE DETERMINED THE TRACK NUMBER THAT CONTAINS THE -; DESIRED SECTOR. -; -TRKSEC4:POP HL ; GET TRACK NUMBER (HL). - PUSH BC - PUSH DE - PUSH HL - EX DE,HL - LD HL,(OFFSET) ; ADJUST FOR FIRST TRACK OFFSET. - ADD HL,DE - LD B,H - LD C,L - CALL SETTRK ; SELECT THIS TRACK. - POP DE ; RESET CURRENT TRACK POINTER. - LD HL,(SCRATCH2) - LD (HL),E - INC HL - LD (HL),D - POP DE - LD HL,(SCRATCH3) ; RESET THE FIRST SECTOR ON THIS TRACK. - LD (HL),E - INC HL - LD (HL),D - POP BC - LD A,C ; NOW SUBTRACT THE DESIRED ONE. - SUB E ; TO MAKE IT RELATIVE (1-# SECTORS/TRACK). - LD C,A - LD A,B - SBC A,D - LD B,A - LD HL,(XLATE) ; TRANSLATE THIS SECTOR ACCORDING TO THIS TABLE. - EX DE,HL - CALL SECTRN ; LET THE BIOS TRANSLATE IT. - LD C,L - LD B,H - JP SETSEC ; AND SELECT IT. -; -; COMPUTE BLOCK NUMBER FROM RECORD NUMBER (SAVNREC) AND -; EXTENT NUMBER (SAVEXT). -; -GETBLOCK: - LD HL,#BLKSHFT ; GET LOGICAL TO PHYSICAL CONVERSION. - LD C,(HL) ; NOTE THAT THIS IS BASE 2 LOG OF RATIO. - LD A,(SAVNREC) ; GET RECORD NUMBER. -GETBLK1:OR A ; COMPUTE (A)=(A)/2^BLKSHFT. - RRA - DEC C - JP NZ,GETBLK1 - LD B,A ; SAVE RESULT IN (B). - LD A,#8 - SUB (HL) - LD C,A ; COMPUTE (C)=8-BLKSHFT. - LD A,(SAVEXT) -GETBLK2:DEC C ; COMPUTE (A)=SAVEXT*2^(8-BLKSHFT). - JP Z,GETBLK3 - OR A - RLA - JP GETBLK2 -GETBLK3:ADD A,B - RET -; -; ROUTINE TO EXTRACT THE (BC) BLOCK BYTE FROM THE FCB POINTED -; TO BY (PARAMS). IF THIS IS A BIG-DISK, THEN THESE ARE 16 BIT -; BLOCK NUMBERS, ELSE THEY ARE 8 BIT NUMBERS. -; NUMBER IS RETURNED IN (HL). -; -EXTBLK: LD HL,(PARAMS) ; GET FCB ADDRESS. - LD DE,#16 ; BLOCK NUMBERS START 16 BYTES INTO FCB. - ADD HL,DE - ADD HL,BC - LD A,(BIGDISK) ; ARE WE USING A BIG-DISK? - OR A - JP Z,EXTBLK1 - LD L,(HL) ; NO, EXTRACT AN 8 BIT NUMBER FROM THE FCB. - LD H,#0 - RET -EXTBLK1:ADD HL,BC ; YES, EXTRACT A 16 BIT NUMBER. - LD E,(HL) - INC HL - LD D,(HL) - EX DE,HL ; RETURN IN (HL). - RET -; -; COMPUTE BLOCK NUMBER. -; -COMBLK: CALL GETBLOCK - LD C,A - LD B,#0 - CALL EXTBLK - LD (BLKNMBR),HL - RET -; -; CHECK FOR A ZERO BLOCK NUMBER (UNUSED). -; -CHKBLK: LD HL,(BLKNMBR) - LD A,L ; IS IT ZERO? - OR H - RET -; -; ADJUST PHYSICAL BLOCK (BLKNMBR) AND CONVERT TO LOGICAL -; SECTOR (LOGSECT). THIS IS THE STARTING SECTOR OF THIS BLOCK. -; THE ACTUAL SECTOR OF INTEREST IS THEN ADDED TO THIS AND THE -; RESULTING SECTOR NUMBER IS STORED BACK IN (BLKNMBR). THIS -; WILL STILL HAVE TO BE ADJUSTED FOR THE TRACK NUMBER. -; -LOGICAL:LD A,(BLKSHFT) ; GET LOG2(PHYSICAL/LOGICAL SECTORS). - LD HL,(BLKNMBR) ; GET PHYSICAL SECTOR DESIRED. -LOGICL1:ADD HL,HL ; COMPUTE LOGICAL SECTOR NUMBER. - DEC A ; NOTE LOGICAL SECTORS ARE 128 BYTES LONG. - JP NZ,LOGICL1 - LD (LOGSECT),HL ; SAVE LOGICAL SECTOR. - LD A,(BLKMASK) ; GET BLOCK MASK. - LD C,A - LD A,(SAVNREC) ; GET NEXT SECTOR TO ACCESS. - AND C ; EXTRACT THE RELATIVE POSITION WITHIN PHYSICAL BLOCK. - OR L ; AND ADD IT TOO LOGICAL SECTOR. - LD L,A - LD (BLKNMBR),HL ; AND STORE. - RET -; -; SET (HL) TO POINT TO EXTENT BYTE IN FCB. -; -SETEXT: LD HL,(PARAMS) - LD DE,#12 ; IT IS THE TWELTH BYTE. - ADD HL,DE - RET -; -; SET (HL) TO POINT TO RECORD COUNT BYTE IN FCB AND (DE) TO -; NEXT RECORD NUMBER BYTE. -; -SETHLDE:LD HL,(PARAMS) - LD DE,#15 ; RECORD COUNT BYTE (#15). - ADD HL,DE - EX DE,HL - LD HL,#17 ; NEXT RECORD NUMBER (#32). - ADD HL,DE - RET -; -; SAVE CURRENT FILE DATA FROM FCB. -; -STRDATA:CALL SETHLDE - LD A,(HL) ; GET AND STORE RECORD COUNT BYTE. - LD (SAVNREC),A - EX DE,HL - LD A,(HL) ; GET AND STORE NEXT RECORD NUMBER BYTE. - LD (SAVNXT),A - CALL SETEXT ; POINT TO EXTENT BYTE. - LD A,(EXTMASK) ; GET EXTENT MASK. - AND (HL) - LD (SAVEXT),A ; AND SAVE EXTENT HERE. - RET -; -; SET THE NEXT RECORD TO ACCESS. IF (MODE) IS SET TO 2, THEN -; THE LAST RECORD BYTE (SAVNREC) HAS THE CORRECT NUMBER TO ACCESS. -; FOR S.EQUENTIAL ACCESS, (MODE) WILL BE .EQUAL TO 1. -; -SETNREC:CALL SETHLDE - LD A,(MODE) ; GET S.EQUENTIAL FLAG (=1). - CP #2 ; A 2 INDICATES THAT NO ADDER IS NEEDED. - JP NZ,STNREC1 - XOR A ; CLEAR ADDER (RANDOM ACCESS?). -STNREC1:LD C,A - LD A,(SAVNREC) ; GET LAST RECORD NUMBER. - ADD A,C ; INCREMENT RECORD COUNT. - LD (HL),A ; AND SET FCB'S NEXT RECORD BYTE. - EX DE,HL - LD A,(SAVNXT) ; GET NEXT RECORD BYTE FROM STORAGE. - LD (HL),A ; AND PUT THIS INTO FCB AS NUMBER OF RECORDS USED. - RET -; -; SHIFT (HL) RIGHT (C) BITS. -; -SHIFTR: INC C -SHIFTR1:DEC C - RET Z - LD A,H - OR A - RRA - LD H,A - LD A,L - RRA - LD L,A - JP SHIFTR1 -; -; COMPUTE THE CHECK-SUM FOR THE DIRECTORY BUFFER. RETURN -; INTEGER SUM IN (A). -; -CHECKSUM: - LD C,#128 ; LENGTH OF BUFFER. - LD HL,(DIRBUF) ; GET ITS LOCATION. - XOR A ; CLEAR SUMMATION BYTE. -CHKSUM1:ADD A,(HL) ; AND COMPUTE SUM IGNORING CARRIES. - INC HL - DEC C - JP NZ,CHKSUM1 - RET -; -; SHIFT (HL) LEFT (C) BITS. -; -SHIFTL: INC C -SHIFTL1:DEC C - RET Z - ADD HL,HL ; SHIFT LEFT 1 BIT. - JP SHIFTL1 -; -; ROUTINE TO SET A BIT IN A 16 BIT VALUE CONTAINED IN (BC). -; THE BIT SET DEPENDS ON THE CURRENT DRIVE SELECTION. -; -SETBIT: PUSH BC ; SAVE 16 BIT WORD. - LD A,(ACTIVE) ; GET ACTIVE DRIVE. - LD C,A - LD HL,#1 - CALL SHIFTL ; SHIFT BIT 0 INTO PLACE. - POP BC ; NOW 'OR' THIS WITH THE ORIGINAL WORD. - LD A,C - OR L - LD L,A ; LOW BYTE DONE, DO HIGH BYTE. - LD A,B - OR H - LD H,A - RET -; -; EXTRACT THE WRITE PROTECT STATUS BIT FOR THE CURRENT DRIVE. -; THE RESULT IS RETURNED IN (A), BIT 0. -; -GETWPRT:LD HL,(WRTPRT) ; GET STATUS BYTES. - LD A,(ACTIVE) ; WHICH DRIVE IS CURRENT? - LD C,A - CALL SHIFTR ; SHIFT STATUS SUCH THAT BIT 0 IS THE - LD A,L ; ONE OF INTEREST FOR THIS DRIVE. - AND #1 ; AND ISOLATE IT. - RET -; -; FUNCTION TO WRITE PROTECT THE CURRENT DISK. -; -WRTPRTD:LD HL,#WRTPRT ; POINT TO STATUS WORD. - LD C,(HL) ; SET (BC) .EQUAL TO THE STATUS. - INC HL - LD B,(HL) - CALL SETBIT ; AND SET THIS BIT ACCORDING TO CURRENT DRIVE. - LD (WRTPRT),HL ; THEN SAVE. - LD HL,(DIRSIZE) ; NOW SAVE DIRECTORY SIZE LIMIT. - INC HL ; REMEMBER THE LAST ONE. - EX DE,HL - LD HL,(SCRATCH1) ; AND STORE IT HERE. - LD (HL),E ; PUT LOW BYTE. - INC HL - LD (HL),D ; THEN HIGH BYTE. - RET -; -; CHECK FOR A READ ONLY FILE. -; -CHKROFL:CALL FCB2HL ; SET (HL) TO FILE ENTRY IN DIRECTORY BUFFER. -CKROF1: LD DE,#9 ; LOOK AT BIT 7 OF THE NINTH BYTE. - ADD HL,DE - LD A,(HL) - RLA - RET NC ; RETURN IF OK. - LD HL,#ROFILE ; ELSE, PRINT ERROR MESSAGE AND TERMINATE. - JP JUMPHL -; -; CHECK THE WRITE PROTECT STATUS OF THE ACTIVE DISK. -; -CHKWPRT:CALL GETWPRT - RET Z ; RETURN IF OK. - LD HL,#RODISK ; ELSE PRINT MESSAGE AND TERMINATE. - JP JUMPHL -; -; ROUTINE TO SET (HL) POINTING TO THE PROPER ENTRY IN THE -; DIRECTORY BUFFER. -; -FCB2HL: LD HL,(DIRBUF) ; GET ADDRESS OF BUFFER. - LD A,(FCBPOS) ; RELATIVE POSITION OF FILE. -; -; ROUTINE TO ADD (A) TO (HL). -; -ADDA2HL:ADD A,L - LD L,A - RET NC - INC H ; TAKE CARE OF ANY CARRY. - RET -; -; ROUTINE TO GET THE 'S2' BYTE FROM THE FCB SUPPLIED IN -; THE INITIAL PARAMETER SPECIFICATION. -; -GETS2: LD HL,(PARAMS) ; GET ADDRESS OF FCB. - LD DE,#14 ; RELATIVE POSITION OF 'S2'. - ADD HL,DE - LD A,(HL) ; EXTRACT THIS BYTE. - RET -; -; CLEAR THE 'S2' BYTE IN THE FCB. -; -CLEARS2:CALL GETS2 ; THIS SETS (HL) POINTING TO IT. - LD (HL),#0 ; NOW CLEAR IT. - RET -; -; SET BIT 7 IN THE 'S2' BYTE OF THE FCB. -; -SETS2B7:CALL GETS2 ; GET THE BYTE. - OR #0x80 ; AND SET BIT 7. - LD (HL),A ; THEN STORE. - RET -; -; COMPARE (FILEPOS) WITH (SCRATCH1) AND SET FLAGS BASED ON -; THE DIFFERENCE. THIS CHECKS TO SEE IF THERE ARE MORE FILE -; NAMES IN THE DIRECTORY. WE ARE AT (FILEPOS) AND THERE ARE -; (SCRATCH1) OF THEM TO CHECK. -; -MOREFLS:LD HL,(FILEPOS) ; WE ARE HERE. - EX DE,HL - LD HL,(SCRATCH1) ; AND DON'T GO PAST HERE. - LD A,E ; COMPUTE DIFFERENCE BUT DON'T KEEP. - SUB (HL) - INC HL - LD A,D - SBC A,(HL) ; SET CARRY IF NO MORE NAMES. - RET -; -; CALL THIS ROUTINE TO PREVENT (SCRATCH1) FROM BEING GREATER -; THAN (FILEPOS). -; -CHKNMBR:CALL MOREFLS ; SCRATCH1 TOO BIG? - RET C - INC DE ; YES, RESET IT TO (FILEPOS). - LD (HL),D - DEC HL - LD (HL),E - RET -; -; COMPUTE (HL)=(DE)-(HL) -; -SUBHL: LD A,E ; COMPUTE DIFFERENCE. - SUB L - LD L,A ; STORE LOW BYTE. - LD A,D - SBC A,H - LD H,A ; AND THEN HIGH BYTE. - RET -; -; SET THE DIRECTORY CHECKSUM BYTE. -; -SETDIR: LD C,#0xFF -; -; ROUTINE TO SET OR COMPARE THE DIRECTORY CHECKSUM BYTE. IF -; (C)=0FFH, THEN THIS WILL SET THE CHECKSUM BYTE. ELSE THE BYTE -; WILL BE CHECKED. IF THE CHECK FAILS (THE DISK HAS BEEN CHANGED), -; THEN THIS DISK WILL BE WRITE PROTECTED. -; -CHECKDIR: - LD HL,(CKSUMTBL) - EX DE,HL - LD HL,(ALLOC1) - CALL SUBHL - RET NC ; OK IF (CKSUMTBL) > (ALLOC1), SO RETURN. - PUSH BC - CALL CHECKSUM ; ELSE COMPUTE CHECKSUM. - LD HL,(CHKVECT) ; GET ADDRESS OF CHECKSUM TABLE. - EX DE,HL - LD HL,(CKSUMTBL) - ADD HL,DE ; SET (HL) TO POINT TO BYTE FOR THIS DRIVE. - POP BC - INC C ; SET OR CHECK ? - JP Z,CHKDIR1 - CP (HL) ; CHECK THEM. - RET Z ; RETURN IF THEY ARE THE SAME. - CALL MOREFLS ; NOT THE SAME, DO WE CARE? - RET NC - CALL WRTPRTD ; YES, MARK THIS AS WRITE PROTECTED. - RET -CHKDIR1:LD (HL),A ; JUST SET THE BYTE. - RET -; -; DO A WRITE TO THE DIRECTORY OF THE CURRENT DISK. -; -DIRWRITE: - CALL SETDIR ; SET CHECKSUM BYTE. - CALL DIRDMA ; SET DIRECTORY DMA ADDRESS. - LD C,#1 ; TELL THE BIOS TO ACTUALLY WRITE. - CALL DOWRITE ; THEN DO THE WRITE. - JP DEFDMA -; -; READ FROM THE DIRECTORY. -; -DIRREAD:CALL DIRDMA ; SET THE DIRECTORY DMA ADDRESS. - CALL DOREAD ; AND READ IT. -; -; ROUTINE TO SET THE DMA ADDRESS TO THE USERS CHOICE. -; -DEFDMA: LD HL,#USERDMA ; RESET THE DEFAULT DMA ADDRESS AND RETURN. - JP DIRDMA1 -; -; ROUTINE TO SET THE DMA ADDRESS FOR DIRECTORY WORK. -; -DIRDMA: LD HL,#DIRBUF -; -; SET THE DMA ADDRESS. ON ENTRY, (HL) POINTS TO -; WORD CONTAINING THE DESIRED DMA ADDRESS. -; -DIRDMA1:LD C,(HL) - INC HL - LD B,(HL) ; SETUP (BC) AND GO TO THE BIOS TO SET IT. - JP SETDMA -; -; MOVE THE DIRECTORY BUFFER INTO USER'S DMA SPACE. -; -MOVEDIR:LD HL,(DIRBUF) ; BUFFER IS LOCATED HERE, AND - EX DE,HL - LD HL,(USERDMA) ; PUT IT HERE. - LD C,#128 ; THIS IS ITS LENGTH. - JP DE2HL ; MOVE IT NOW AND RETURN. -; -; CHECK (FILEPOS) AND SET THE ZERO FLAG IF IT .EQUALS 0FFFFH. -; -CKFILPOS: - LD HL,#FILEPOS - LD A,(HL) - INC HL - CP (HL) ; ARE BOTH BYTES THE SAME? - RET NZ - INC A ; YES, BUT ARE THEY EACH 0FFH? - RET -; -; SET LOCATION (FILEPOS) TO 0FFFFH. -; -STFILPOS: - LD HL,#0x0FFFF - LD (FILEPOS),HL - RET -; -; MOVE ON TO THE NEXT FILE POSITION WITHIN THE CURRENT -; DIRECTORY BUFFER. IF NO MORE EXIST, SET POINTER TO 0FFFFH -; AND THE CALLING ROUTINE WILL CHECK FOR THIS. ENTER WITH (C) -; .EQUAL TO 0FFH TO CAUSE THE CHECKSUM BYTE TO BE SET, ELSE WE -; WILL CHECK THIS DISK AND SET WRITE PROTECT IF CHECKSUMS ARE -; NOT THE SAME (APPLIES ONLY IF ANOTHER DIRECTORY SECTOR MUST -; BE READ). -; -NXENTRY:LD HL,(DIRSIZE) ; GET DIRECTORY ENTRY SIZE LIMIT. - EX DE,HL - LD HL,(FILEPOS) ; GET CURRENT COUNT. - INC HL ; GO ON TO THE NEXT ONE. - LD (FILEPOS),HL - CALL SUBHL ; (HL)=(DIRSIZE)-(FILEPOS) - JP NC,NXENT1 ; IS THERE MORE ROOM LEFT? - JP STFILPOS ; NO. SET THIS FLAG AND RETURN. -NXENT1: LD A,(FILEPOS) ; GET FILE POSITION WITHIN DIRECTORY. - AND #3 ; ONLY LOOK WITHIN THIS SECTOR (ONLY 4 ENTRIES FIT). - LD B,#5 ; CONVERT TO RELATIVE POSITION (32 BYTES EACH). -NXENT2: ADD A,A ; NOTE THAT THIS IS NOT EFFICIENT CODE. - DEC B ; 5 'ADD A'S WOULD BE BETTER. - JP NZ,NXENT2 - LD (FCBPOS),A ; SAVE IT AS POSITION OF FCB. - OR A - RET NZ ; RETURN IF WE ARE WITHIN BUFFER. - PUSH BC - CALL TRKSEC ; WE NEED THE NEXT DIRECTORY SECTOR. - CALL DIRREAD - POP BC - JP CHECKDIR -; -; ROUTINE TO TO GET A BIT FROM THE DISK SPACE ALLOCATION -; MAP. IT IS RETURNED IN (A), BIT POSITION 0. ON ENTRY TO HERE, -; SET (BC) TO THE BLOCK NUMBER ON THE DISK TO CHECK. -; ON RETURN, (D) WILL CONTAIN THE ORIGINAL BIT POSITION FOR -; THIS BLOCK NUMBER AND (HL) WILL POINT TO THE ADDRESS FOR IT. -; -CKBITMAP: - LD A,C ; DETERMINE BIT NUMBER OF INTEREST. - AND #7 ; COMPUTE (D)=(E)=(C AND 7)+1. - INC A - LD E,A ; SAVE PARTICULAR BIT NUMBER. - LD D,A -; -; COMPUTE (BC)=(BC)/8. -; - LD A,C - RRCA ; NOW SHIFT RIGHT 3 BITS. - RRCA - RRCA - AND #0x1F ; AND CLEAR BITS 7,6,5. - LD C,A - LD A,B - ADD A,A ; NOW SHIFT (B) INTO BITS 7,6,5. - ADD A,A - ADD A,A - ADD A,A - ADD A,A - OR C ; AND ADD IN (C). - LD C,A ; OK, (C) HA BEEN COMPLETED. - LD A,B ; IS THERE A BETTER WAY OF DOING THIS? - RRCA - RRCA - RRCA - AND #0x1F - LD B,A ; AND NOW (B) IS COMPLETED. -; -; USE THIS AS AN OFFSET INTO THE DISK SPACE ALLOCATION -; TABLE. -; - LD HL,(ALOCVECT) - ADD HL,BC - LD A,(HL) ; NOW GET CORRECT BYTE. -CKBMAP1:RLCA ; GET CORRECT BIT INTO POSITION 0. - DEC E - JP NZ,CKBMAP1 - RET -; -; SET OR CLEAR THE BIT MAP SUCH THAT BLOCK NUMBER (BC) WILL BE MARKED -; AS USED. ON ENTRY, IF (E)=0 THEN THIS BIT WILL BE CLEARED, IF IT .EQUALS -; 1 THEN IT WILL BE SET (DON'T USE ANYOTHER VALUES). -; -STBITMAP: - PUSH DE - CALL CKBITMAP ; GET THE BYTE OF INTEREST. - AND #0x0FE ; CLEAR THE AFFECTED BIT. - POP BC - OR C ; AND NOW SET IT ACORDING TO (C). -; -; ENTRY TO RESTORE THE ORIGINAL BIT POSITION AND THEN STORE -; IN TABLE. (A) CONTAINS THE VALUE, (D) CONTAINS THE BIT -; POSITION (1-8), AND (HL) POINTS TO THE ADDRESS WITHIN THE -; SPACE ALLOCATION TABLE FOR THIS BYTE. -; -STBMAP1:RRCA ; RESTORE ORIGINAL BIT POSITION. - DEC D - JP NZ,STBMAP1 - LD (HL),A ; AND STOR BYTE IN TABLE. - RET -; -; SET/CLEAR SPACE USED BITS IN ALLOCATION MAP FOR THIS FILE. -; ON ENTRY, (C)=1 TO SET THE MAP AND (C)=0 TO CLEAR IT. -; -SETFILE:CALL FCB2HL ; GET ADDRESS OF FCB - LD DE,#16 - ADD HL,DE ; GET TO BLOCK NUMBER BYTES. - PUSH BC - LD C,#17 ; CHECK ALL 17 BYTES (MAX) OF TABLE. -SETFL1: POP DE - DEC C ; DONE ALL BYTES YET? - RET Z - PUSH DE - LD A,(BIGDISK) ; CHECK DISK SIZE FOR 16 BIT BLOCK NUMBERS. - OR A - JP Z,SETFL2 - PUSH BC ; ONLY 8 BIT NUMBERS. SET (BC) TO THIS ONE. - PUSH HL - LD C,(HL) ; GET LOW BYTE FROM TABLE, ALWAYS - LD B,#0 ; SET HIGH BYTE TO ZERO. - JP SETFL3 -SETFL2: DEC C ; FOR 16 BIT BLOCK NUMBERS, ADJUST COUNTER. - PUSH BC - LD C,(HL) ; NOW GET BOTH THE LOW AND HIGH BYTES. - INC HL - LD B,(HL) - PUSH HL -SETFL3: LD A,C ; BLOCK USED? - OR B - JP Z,SETFL4 - LD HL,(DSKSIZE) ; IS THIS BLOCK NUMBER WITHIN THE - LD A,L ; SPACE ON THE DISK? - SUB C - LD A,H - SBC A,B - CALL NC,STBITMAP ; YES, SET THE PROPER BIT. -SETFL4: POP HL ; POINT TO NEXT BLOCK NUMBER IN FCB. - INC HL - POP BC - JP SETFL1 -; -; CONSTRUCT THE SPACE USED ALLOCATION BIT MAP FOR THE ACTIVE -; DRIVE. IF A FILE NAME STARTS WITH '$' AND IT IS UNDER THE -; CURRENT USER NUMBER, THEN (STATUS) IS SET TO MINUS 1. OTHERWISE -; IT IS NOT SET AT ALL. -; -BITMAP: LD HL,(DSKSIZE) ; COMPUTE SIZE OF ALLOCATION TABLE. - LD C,#3 - CALL SHIFTR ; (HL)=(HL)/8. - INC HL ; AT LEASE 1 BYTE. - LD B,H - LD C,L ; SET (BC) TO THE ALLOCATION TABLE LENGTH. -; -; INITIALIZE THE BITMAP FOR THIS DRIVE. RIGHT NOW, THE FIRST -; TWO BYTES ARE SPECIFIED BY THE DISK PARAMETER BLOCK. HOWEVER -; A PATCH COULD BE ENTERED HERE IF IT WERE NECESSARY TO SETUP -; THIS TABLE IN A SPECIAL MANNOR. FOR EXAMPLE, THE BIOS COULD -; DETERMINE LOCATIONS OF 'BAD BLOCKS' AND SET THEM AS ALREADY -; 'USED' IN THE MAP. -; - LD HL,(ALOCVECT) ; NOW ZERO OUT THE TABLE NOW. -BITMAP1:LD (HL),#0 - INC HL - DEC BC - LD A,B - OR C - JP NZ,BITMAP1 - LD HL,(ALLOC0) ; GET INITIAL SPACE USED BY DIRECTORY. - EX DE,HL - LD HL,(ALOCVECT) ; AND PUT THIS INTO MAP. - LD (HL),E - INC HL - LD (HL),D -; -; END OF INITIALIZATION PORTION. -; - CALL HOMEDRV ; NOW HOME THE DRIVE. - LD HL,(SCRATCH1) - LD (HL),#3 ; FORCE NEXT DIRECTORY R.EQUEST TO READ - INC HL ; IN A SECTOR. - LD (HL),#0 - CALL STFILPOS ; CLEAR INITIAL FILE POSITION ALSO. -BITMAP2:LD C,#0x0FF ; READ NEXT FILE NAME IN DIRECTORY - CALL NXENTRY ; AND SET CHECKSUM BYTE. - CALL CKFILPOS ; IS THERE ANOTHER FILE? - RET Z - CALL FCB2HL ; YES, GET ITS ADDRESS. - LD A,#0x0E5 - CP (HL) ; EMPTY FILE ENTRY? - JP Z,BITMAP2 - LD A,(USERNO) ; NO, CORRECT USER NUMBER? - CP (HL) - JP NZ,BITMAP3 - INC HL - LD A,(HL) ; YES, DOES NAME START WITH A '$'? - SUB #DOLLAR - JP NZ,BITMAP3 - DEC A ; YES, SET ATATUS TO MINUS ONE. - LD (STATUS),A -BITMAP3:LD C,#1 ; NOW SET THIS FILE'S SPACE AS USED IN BIT MAP. - CALL SETFILE - CALL CHKNMBR ; KEEP (SCRATCH1) IN BOUNDS. - JP BITMAP2 -; -; SET THE STATUS (STATUS) AND RETURN. -; -STSTATUS: - LD A,(FNDSTAT) - JP SETSTAT -; -; CHECK EXTENTS IN (A) AND (C). SET THE ZERO FLAG IF THEY -; ARE THE SAME. THE NUMBER OF 16K CHUNKS OF DISK SPACE THAT -; THE DIRECTORY EXTENT COVERS IS EXPRESSAD IS (EXTMASK+1). -; NO REGISTERS ARE MODIFIED. -; -SAMEXT: PUSH BC - PUSH AF - LD A,(EXTMASK) ; GET EXTENT MASK AND USE IT TO - CPL ; TO COMPARE BOTH EXTENT NUMBERS. - LD B,A ; SAVE RESULTING MASK HERE. - LD A,C ; MASK FIRST EXTENT AND SAVE IN (C). - AND B - LD C,A - POP AF ; NOW MASK SECOND EXTENT AND COMPARE - AND B ; WITH THE FIRST ONE. - SUB C - AND #0x1F ; (* ONLY CHECK BUTS 0-4 *) - POP BC ; THE ZERO FLAG IS SET IF THEY ARE THE SAME. - RET ; RESTORE (BC) AND RETURN. -; -; SEARCH FOR THE FIRST OCCURENCE OF A FILE NAME. ON ENTRY, -; REGISTER (C) SHOULD CONTAIN THE NUMBER OF BYTES OF THE FCB -; THAT MUST MATCH. -; -FINDFST:LD A,#0x0FF - LD (FNDSTAT),A - LD HL,#COUNTER ; SAVE CHARACTER COUNT. - LD (HL),C - LD HL,(PARAMS) ; GET FILENAME TO MATCH. - LD (SAVEFCB),HL ; AND SAVE. - CALL STFILPOS ; CLEAR INITIAL FILE POSITION (SET TO 0FFFFH). - CALL HOMEDRV ; HOME THE DRIVE. -; -; ENTRY TO LOCATE THE NEXT OCCURENCE OF A FILENAME WITHIN THE -; DIRECTORY. THE DISK IS NOT EXPECTED TO HAVE BEEN CHANGED. IF -; IT WAS, THEN IT WILL BE WRITE PROTECTED. -; -FINDNXT:LD C,#0 ; WRITE PROTECT THE DISK IF CHANGED. - CALL NXENTRY ; GET NEXT FILENAME ENTRY IN DIRECTORY. - CALL CKFILPOS ; IS FILE POSITION = 0FFFFH? - JP Z,FNDNXT6 ; YES, EXIT NOW THEN. - LD HL,(SAVEFCB) ; SET (DE) POINTING TO FILENAME TO MATCH. - EX DE,HL - LD A,(DE) - CP #0x0E5 ; EMPTY DIRECTORY ENTRY? - JP Z,FNDNXT1 ; (* ARE WE TRYING TO RESERECT ERASED ENTRIES? *) - PUSH DE - CALL MOREFLS ; MORE FILES IN DIRECTORY? - POP DE - JP NC,FNDNXT6 ; NO MORE. EXIT NOW. -FNDNXT1:CALL FCB2HL ; GET ADDRESS OF THIS FCB IN DIRECTORY. - LD A,(COUNTER) ; GET NUMBER OF BYTES (CHARACTERS) TO CHECK. - LD C,A - LD B,#0 ; INITIALIZE BYTE POSITION COUNTER. -FNDNXT2:LD A,C ; ARE WE DONE WITH THE COMPARE? - OR A - JP Z,FNDNXT5 - LD A,(DE) ; NO, CHECK NEXT BYTE. - CP #QUESTION ; DON'T CARE ABOUT THIS CHARACTER? - JP Z,FNDNXT4 - LD A,B ; GET BYTES POSITION IN FCB. - CP #13 ; DON'T CARE ABOUT THE THIRTEENTH BYTE EITHER. - JP Z,FNDNXT4 - CP #12 ; EXTENT BYTE? - LD A,(DE) - JP Z,FNDNXT3 - SUB (HL) ; OTHERWISE COMPARE CHARACTERS. - AND #0x7F - JP NZ,FINDNXT ; NOT THE SAME, CHECK NEXT ENTRY. - JP FNDNXT4 ; SO FAR SO GOOD, KEEP CHECKING. -FNDNXT3:PUSH BC ; CHECK THE EXTENT BYTE HERE. - LD C,(HL) - CALL SAMEXT - POP BC - JP NZ,FINDNXT ; NOT THE SAME, LOOK SOME MORE. -; -; SO FAR THE NAMES COMPARE. BUMP POINTERS TO THE NEXT BYTE -; AND CONTINUE UNTIL ALL (C) CHARACTERS HAVE BEEN CHECKED. -; -FNDNXT4:INC DE ; BUMP POINTERS. - INC HL - INC B - DEC C ; ADJUST CHARACTER COUNTER. - JP FNDNXT2 -FNDNXT5:LD A,(FILEPOS) ; RETURN THE POSITION OF THIS ENTRY. - AND #3 - LD (STATUS),A - LD HL,#FNDSTAT - LD A,(HL) - RLA - RET NC - XOR A - LD (HL),A - RET -; -; FILENAME WAS NOT FOUND. SET APPROPRIATE STATUS. -; -FNDNXT6:CALL STFILPOS ; SET (FILEPOS) TO 0FFFFH. - LD A,#0x0FF ; SAY NOT LOCATED. - JP SETSTAT -; -; ERASE FILES FROM THE DIRECTORY. ONLY THE FIRST BYTE OF THE -; FCB WILL BE AFFECTED. IT IS SET TO (E5). -; -ERAFILE:CALL CHKWPRT ; IS DISK WRITE PROTECTED? - LD C,#12 ; ONLY COMPARE FILE NAMES. - CALL FINDFST ; GET FIRST FILE NAME. -ERAFIL1:CALL CKFILPOS ; ANY FOUND? - RET Z ; NOPE, WE MUST BE DONE. - CALL CHKROFL ; IS FILE READ ONLY? - CALL FCB2HL ; NOPE, GET ADDRESS OF FCB AND - LD (HL),#0x0E5 ; SET FIRST BYTE TO 'EMPTY'. - LD C,#0 ; CLEAR THE SPACE FROM THE BIT MAP. - CALL SETFILE - CALL DIRWRITE ; NOW WRITE THE DIRECTORY SECTOR BACK OUT. - CALL FINDNXT ; FIND THE NEXT FILE NAME. - JP ERAFIL1 ; AND REPEAT PROCESS. -; -; LOOK THROUGH THE SPACE ALLOCATION MAP (BIT MAP) FOR THE -; NEXT AVAILABLE BLOCK. START SEARCHING AT BLOCK NUMBER (BC-1). -; THE SEARCH PROCEDURE IS TO LOOK FOR AN EMPTY BLOCK THAT IS -; BEFORE THE STARTING BLOCK. IF NOT EMPTY, LOOK AT A LATER -; BLOCK NUMBER. IN THIS WAY, WE RETURN THE CLOSEST EMPTY BLOCK -; ON EITHER SIDE OF THE 'TARGET' BLOCK NUMBER. THIS WILL SPEED -; ACCESS ON RANDOM DEVICES. FOR SERIAL DEVICES, THIS SHOULD BE -; CHANGED TO LOOK IN THE FORWARD DIRECTION FIRST AND THEN START -; AT THE FRONT AND SEARCH SOME MORE. -; -; ON RETURN, (DE)= BLOCK NUMBER THAT IS EMPTY AND (HL) =0 -; IF NO EMPRY BLOCK WAS FOUND. -; -FNDSPACE: - LD D,B ; SET (DE) AS THE BLOCK THAT IS CHECKED. - LD E,C -; -; LOOK BEFORE TARGET BLOCK. REGISTERS (BC) ARE USED AS THE LOWER -; POINTER AND (DE) AS THE UPPER POINTER. -; -FNDSPA1:LD A,C ; IS BLOCK 0 SPECIFIED? - OR B - JP Z,FNDSPA2 - DEC BC ; NOPE, CHECK PREVIOUS BLOCK. - PUSH DE - PUSH BC - CALL CKBITMAP - RRA ; IS THIS BLOCK EMPTY? - JP NC,FNDSPA3 ; YES. USE THIS. -; -; NOTE THAT THE ABOVE LOGIC GETS THE FIRST BLOCK THAT IT FINDS -; THAT IS EMPTY. THUS A FILE COULD BE WRITTEN 'BACKWARD' MAKING -; IT VERY SLOW TO ACCESS. THIS COULD BE CHANGED TO LOOK FOR THE -; FIRST EMPTY BLOCK AND THEN CONTINUE UNTIL THE START OF THIS -; EMPTY SPACE IS LOCATED AND THEN USED THAT STARTING BLOCK. -; THIS SHOULD HELP SPEED UP ACCESS TO SOME FILES ESPECIALLY ON -; A WELL USED DISK WITH LOTS OF FAIRLY SMALL 'HOLES'. -; - POP BC ; NOPE, CHECK SOME MORE. - POP DE -; -; NOW LOOK AFTER TARGET BLOCK. -; -FNDSPA2:LD HL,(DSKSIZE) ; IS BLOCK (DE) WITHIN DISK LIMITS? - LD A,E - SUB L - LD A,D - SBC A,H - JP NC,FNDSPA4 - INC DE ; YES, MOVE ON TO NEXT ONE. - PUSH BC - PUSH DE - LD B,D - LD C,E - CALL CKBITMAP ; CHECK IT. - RRA ; EMPTY? - JP NC,FNDSPA3 - POP DE ; NOPE, CONTINUE SEARCHING. - POP BC - JP FNDSPA1 -; -; EMPTY BLOCK FOUND. SET IT AS USED AND RETURN WITH (HL) -; POINTING TO IT (TRUE?). -; -FNDSPA3:RLA ; RESET BYTE. - INC A ; AND SET BIT 0. - CALL STBMAP1 ; UPDATE BIT MAP. - POP HL ; SET RETURN REGISTERS. - POP DE - RET -; -; FREE BLOCK WAS NOT FOUND. IF (BC) IS NOT ZERO, THEN WE HAVE -; NOT CHECKED ALL OF THE DISK SPACE. -; -FNDSPA4:LD A,C - OR B - JP NZ,FNDSPA1 - LD HL,#0 ; SET 'NOT FOUND' STATUS. - RET -; -; MOVE A COMPLETE FCB ENTRY INTO THE DIRECTORY AND WRITE IT. -; -FCBSET: LD C,#0 - LD E,#32 ; LENGTH OF EACH ENTRY. -; -; MOVE (E) BYTES FROM THE FCB POINTED TO BY (PARAMS) INTO -; FCB IN DIRECTORY STARTING AT RELATIVE BYTE (C). THIS UPDATED -; DIRECTORY BUFFER IS THEN WRITTEN TO THE DISK. -; -UPDATE: PUSH DE - LD B,#0 ; SET (BC) TO RELATIVE BYTE POSITION. - LD HL,(PARAMS) ; GET ADDRESS OF FCB. - ADD HL,BC ; COMPUTE STARTING BYTE. - EX DE,HL - CALL FCB2HL ; GET ADDRESS OF FCB TO UPDATE IN DIRECTORY. - POP BC ; SET (C) TO NUMBER OF BYTES TO CHANGE. - CALL DE2HL -UPDATE1:CALL TRKSEC ; DETERMINE THE TRACK AND SECTOR AFFECTED. - JP DIRWRITE ; THEN WRITE THIS SECTOR OUT. -; -; ROUTINE TO CHANGE THE NAME OF ALL FILES ON THE DISK WITH A -; SPECIFIED NAME. THE FCB CONTAINS THE CURRENT NAME AS THE -; FIRST 12 CHARACTERS AND THE NEW NAME 16 BYTES INTO THE FCB. -; -CHGNAMES: - CALL CHKWPRT ; CHECK FOR A WRITE PROTECTED DISK. - LD C,#12 ; MATCH FIRST 12 BYTES OF FCB ONLY. - CALL FINDFST ; GET FIRST NAME. - LD HL,(PARAMS) ; GET ADDRESS OF FCB. - LD A,(HL) ; GET USER NUMBER. - LD DE,#16 ; MOVE OVER TO DESIRED NAME. - ADD HL,DE - LD (HL),A ; KEEP SAME USER NUMBER. -CHGNAM1:CALL CKFILPOS ; ANY MATCHING FILE FOUND? - RET Z ; NO, WE MUST BE DONE. - CALL CHKROFL ; CHECK FOR READ ONLY FILE. - LD C,#16 ; START 16 BYTES INTO FCB. - LD E,#12 ; AND UPDATE THE FIRST 12 BYTES OF DIRECTORY. - CALL UPDATE - CALL FINDNXT ; GET TE NEXT FILE NAME. - JP CHGNAM1 ; AND CONTINUE. -; -; UPDATE A FILES ATTRIBUTES. THE PROCEDURE IS TO SEARCH FOR -; EVERY FILE WITH THE SAME NAME AS SHOWN IN FCB (IGNORING BIT 7) -; AND THEN TO UPDATE IT (WHICH INCLUDES BIT 7). NO OTHER CHANGES -; ARE MADE. -; -SAVEATTR: - LD C,#12 ; MATCH FIRST 12 BYTES. - CALL FINDFST ; LOOK FOR FIRST FILENAME. -SAVATR1:CALL CKFILPOS ; WAS ONE FOUND? - RET Z ; NOPE, WE MUST BE DONE. - LD C,#0 ; YES, UPDATE THE FIRST 12 BYTES NOW. - LD E,#12 - CALL UPDATE ; UPDATE FILENAME AND WRITE DIRECTORY. - CALL FINDNXT ; AND GET THE NEXT FILE. - JP SAVATR1 ; THEN CONTINUE UNTIL DONE. -; -; OPEN A FILE (NAME SPECIFIED IN FCB). -; -OPENIT: LD C,#15 ; COMPARE THE FIRST 15 BYTES. - CALL FINDFST ; GET THE FIRST ONE IN DIRECTORY. - CALL CKFILPOS ; ANY AT ALL? - RET Z -OPENIT1:CALL SETEXT ; POINT TO EXTENT BYTE WITHIN USERS FCB. - LD A,(HL) ; AND GET IT. - PUSH AF ; SAVE IT AND ADDRESS. - PUSH HL - CALL FCB2HL ; POINT TO FCB IN DIRECTORY. - EX DE,HL - LD HL,(PARAMS) ; THIS IS THE USERS COPY. - LD C,#32 ; MOVE IT INTO USERS SPACE. - PUSH DE - CALL DE2HL - CALL SETS2B7 ; SET BIT 7 IN 'S2' BYTE (UNMODIFIED). - POP DE ; NOW GET THE EXTENT BYTE FROM THIS FCB. - LD HL,#12 - ADD HL,DE - LD C,(HL) ; INTO (C). - LD HL,#15 ; NOW GET THE RECORD COUNT BYTE INTO (B). - ADD HL,DE - LD B,(HL) - POP HL ; KEEP THE SAME EXTENT AS THE USER HAD ORIGINALLY. - POP AF - LD (HL),A - LD A,C ; IS IT THE SAME AS IN THE DIRECTORY FCB? - CP (HL) - LD A,B ; IF YES, THEN USE THE SAME RECORD COUNT. - JP Z,OPENIT2 - LD A,#0 ; IF THE USER SPECIFIED AN EXTENT GREATER THAN - JP C,OPENIT2 ; THE ONE IN THE DIRECTORY, THEN SET RECORD COUNT TO 0. - LD A,#128 ; OTHERWISE SET TO MAXIMUM. -OPENIT2:LD HL,(PARAMS) ; SET RECORD COUNT IN USERS FCB TO (A). - LD DE,#15 - ADD HL,DE ; COMPUTE RELATIVE POSITION. - LD (HL),A ; AND SET THE RECORD COUNT. - RET -; -; MOVE TWO BYTES FROM (DE) TO (HL) IF (AND ONLY IF) (HL) -; POINT TO A ZERO VALUE (16 BIT). -; RETURN WITH ZERO FLAG SET IT (DE) WAS MOVED. REGISTERS (DE) -; AND (HL) ARE NOT CHANGED. HOWEVER (A) IS. -; -MOVEWORD: - LD A,(HL) ; CHECK FOR A ZERO WORD. - INC HL - OR (HL) ; BOTH BYTES ZERO? - DEC HL - RET NZ ; NOPE, JUST RETURN. - LD A,(DE) ; YES, MOVE TWO BYTES FROM (DE) INTO - LD (HL),A ; THIS ZERO SPACE. - INC DE - INC HL - LD A,(DE) - LD (HL),A - DEC DE ; DON'T DISTURB THESE REGISTERS. - DEC HL - RET -; -; GET HERE TO CLOSE A FILE SPECIFIED BY (FCB). -; -CLOSEIT:XOR A ; CLEAR STATUS AND FILE POSITION BYTES. - LD (STATUS),A - LD (FILEPOS),A - LD (FILEPOS+1),A - CALL GETWPRT ; GET WRITE PROTECT BIT FOR THIS DRIVE. - RET NZ ; JUST RETURN IF IT IS SET. - CALL GETS2 ; ELSE GET THE 'S2' BYTE. - AND #0x80 ; AND LOOK AT BIT 7 (FILE UNMODIFIED?). - RET NZ ; JUST RETURN IF SET. - LD C,#15 ; ELSE LOOK UP THIS FILE IN DIRECTORY. - CALL FINDFST - CALL CKFILPOS ; WAS IT FOUND? - RET Z ; JUST RETURN IF NOT. - LD BC,#16 ; SET (HL) POINTING TO RECORDS USED SECTION. - CALL FCB2HL - ADD HL,BC - EX DE,HL - LD HL,(PARAMS) ; DO THE SAME FOR USERS SPECIFIED FCB. - ADD HL,BC - LD C,#16 ; THIS MANY BYTES ARE PRESENT IN THIS EXTENT. -CLOSEIT1: - LD A,(BIGDISK) ; 8 OR 16 BIT RECORD NUMBERS? - OR A - JP Z,CLOSEIT4 - LD A,(HL) ; JUST 8 BIT. GET ONE FROM USERS FCB. - OR A - LD A,(DE) ; NOW GET ONE FROM DIRECTORY FCB. - JP NZ,CLOSEIT2 - LD (HL),A ; USERS BYTE WAS ZERO. UPDATE FROM DIRECTORY. -CLOSEIT2: - OR A - JP NZ,CLOSEIT3 - LD A,(HL) ; DIRECTORIES BYTE WAS ZERO, UPDATE FROM USERS FCB. - LD (DE),A -CLOSEIT3: - CP (HL) ; IF NEITHER ONE OF THESE BYTES WERE ZERO, - JP NZ,CLOSEIT7 ; THEN CLOSE ERROR IF THEY ARE NOT THE SAME. - JP CLOSEIT5 ; OK SO FAR, GET TO NEXT BYTE IN FCBS. -CLOSEIT4: - CALL MOVEWORD ; UPDATE USERS FCB IF IT IS ZERO. - EX DE,HL - CALL MOVEWORD ; UPDATE DIRECTORIES FCB IF IT IS ZERO. - EX DE,HL - LD A,(DE) ; IF THESE TWO VALUES ARE NO DIFFERENT, - CP (HL) ; THEN A CLOSE ERROR OCCURED. - JP NZ,CLOSEIT7 - INC DE ; CHECK SECOND BYTE. - INC HL - LD A,(DE) - CP (HL) - JP NZ,CLOSEIT7 - DEC C ; REMEMBER 16 BIT VALUES. -CLOSEIT5: - INC DE ; BUMP TO NEXT ITEM IN TABLE. - INC HL - DEC C ; THERE ARE 16 ENTRIES ONLY. - JP NZ,CLOSEIT1 ; CONTINUE IF MORE TO DO. - LD BC,#0x0FFEC ; BACKUP 20 PLACES (EXTENT BYTE). - ADD HL,BC - EX DE,HL - ADD HL,BC - LD A,(DE) - CP (HL) ; DIRECTORY'S EXTENT ALREADY GREATER THAN THE - JP C,CLOSEIT6 ; USERS EXTENT? - LD (HL),A ; NO, UPDATE DIRECTORY EXTENT. - LD BC,#3 ; AND UPDATE THE RECORD COUNT BYTE IN - ADD HL,BC ; DIRECTORIES FCB. - EX DE,HL - ADD HL,BC - LD A,(HL) ; GET FROM USER. - LD (DE),A ; AND PUT IN DIRECTORY. -CLOSEIT6: - LD A,#0x0FF ; SET 'WAS OPEN AND IS NOW CLOSED' BYTE. - LD (CLOSEFLG),A - JP UPDATE1 ; UPDATE THE DIRECTORY NOW. -CLOSEIT7: - LD HL,#STATUS ; SET RETURN STATUS AND THEN RETURN. - DEC (HL) - RET -; -; ROUTINE TO GET THE NEXT EMPTY SPACE IN THE DIRECTORY. IT -; WILL THEN BE CLEARED FOR USE. -; -GETEMPTY: - CALL CHKWPRT ; MAKE SURE DISK IS NOT WRITE PROTECTED. - LD HL,(PARAMS) ; SAVE CURRENT PARAMETERS (FCB). - PUSH HL - LD HL,#EMPTYFCB ; USE SPECIAL ONE FOR EMPTY SPACE. - LD (PARAMS),HL - LD C,#1 ; SEARCH FOR FIRST EMPTY SPOT IN DIRECTORY. - CALL FINDFST ; (* ONLY CHECK FIRST BYTE *) - CALL CKFILPOS ; NONE? - POP HL - LD (PARAMS),HL ; RESTORE ORIGINAL FCB ADDRESS. - RET Z ; RETURN IF NO MORE SPACE. - EX DE,HL - LD HL,#15 ; POINT TO NUMBER OF RECORDS FOR THIS FILE. - ADD HL,DE - LD C,#17 ; AND CLEAR ALL OF THIS SPACE. - XOR A -GETMT1: LD (HL),A - INC HL - DEC C - JP NZ,GETMT1 - LD HL,#13 ; CLEAR THE 'S1' BYTE ALSO. - ADD HL,DE - LD (HL),A - CALL CHKNMBR ; KEEP (SCRATCH1) WITHIN BOUNDS. - CALL FCBSET ; WRITE OUT THIS FCB ENTRY TO DIRECTORY. - JP SETS2B7 ; SET 'S2' BYTE BIT 7 (UNMODIFIED AT PRESENT). -; -; ROUTINE TO CLOSE THE CURRENT EXTENT AND OPEN THE NEXT ONE -; FOR READING. -; -GETNEXT:XOR A - LD (CLOSEFLG),A ; CLEAR CLOSE FLAG. - CALL CLOSEIT ; CLOSE THIS EXTENT. - CALL CKFILPOS - RET Z ; NOT THERE??? - LD HL,(PARAMS) ; GET EXTENT BYTE. - LD BC,#12 - ADD HL,BC - LD A,(HL) ; AND INCREMENT IT. - INC A - AND #0x1F ; KEEP WITHIN RANGE 0-31. - LD (HL),A - JP Z,GTNEXT1 ; OVERFLOW? - LD B,A ; MASK EXTENT BYTE. - LD A,(EXTMASK) - AND B - LD HL,#CLOSEFLG ; CHECK CLOSE FLAG (0FFH IS OK). - AND (HL) - JP Z,GTNEXT2 ; IF ZERO, WE MUST READ IN NEXT EXTENT. - JP GTNEXT3 ; ELSE, IT IS ALREADY IN MEMORY. -GTNEXT1:LD BC,#2 ; POINT TO THE 'S2' BYTE. - ADD HL,BC - INC (HL) ; AND BUMP IT. - LD A,(HL) ; TOO MANY EXTENTS? - AND #0x0F - JP Z,GTNEXT5 ; YES, SET ERROR CODE. -; -; GET HERE TO OPEN THE NEXT EXTENT. -; -GTNEXT2:LD C,#15 ; SET TO CHECK FIRST 15 BYTES OF FCB. - CALL FINDFST ; FIND THE FIRST ONE. - CALL CKFILPOS ; NONE AVAILABLE? - JP NZ,GTNEXT3 - LD A,(R.DWRTFLG) ; NO EXTENT PRESENT. CAN WE OPEN AN EMPTY ONE? - INC A ; 0FFH MEANS READING (SO NOT POSSIBLE). - JP Z,GTNEXT5 ; OR AN ERROR. - CALL GETEMPTY ; WE ARE WRITING, GET AN EMPTY ENTRY. - CALL CKFILPOS ; NONE? - JP Z,GTNEXT5 ; ERROR IF TRUE. - JP GTNEXT4 ; ELSE WE ARE ALMOST DONE. -GTNEXT3:CALL OPENIT1 ; OPEN THIS EXTENT. -GTNEXT4:CALL STRDATA ; MOVE IN UPDATED DATA (REC #, EXTENT #, ETC.) - XOR A ; CLEAR STATUS AND RETURN. - JP SETSTAT -; -; ERROR IN EXTENDING THE FILE. TOO MANY EXTENTS WERE NEEDED -; OR NOT ENOUGH SPACE ON THE DISK. -; -GTNEXT5:CALL IOERR1 ; SET ERROR CODE, CLEAR BIT 7 OF 'S2' - JP SETS2B7 ; SO THIS IS NOT WRITTEN ON A CLOSE. -; -; READ A S.EQUENTIAL FILE. -; -RDSEQ: LD A,#1 ; SET S.EQUENTIAL ACCESS MODE. - LD (MODE),A -RDSEQ1: LD A,#0x0FF ; DON'T ALLOW READING UNWRITTEN SPACE. - LD (R.DWRTFLG),A - CALL STRDATA ; PUT REC# AND EXT# INTO FCB. - LD A,(SAVNREC) ; GET NEXT RECORD TO READ. - LD HL,#SAVNXT ; GET NUMBER OF RECORDS IN EXTENT. - CP (HL) ; WITHIN THIS EXTENT? - JP C,RDSEQ2 - CP #128 ; NO. IS THIS EXTENT FULLY USED? - JP NZ,RDSEQ3 ; NO. END-OF-FILE. - CALL GETNEXT ; YES, OPEN THE NEXT ONE. - XOR A ; RESET NEXT RECORD TO READ. - LD (SAVNREC),A - LD A,(STATUS) ; CHECK ON OPEN, SUCCESSFUL? - OR A - JP NZ,RDSEQ3 ; NO, ERROR. -RDSEQ2: CALL COMBLK ; OK. COMPUTE BLOCK NUMBER TO READ. - CALL CHKBLK ; CHECK IT. WITHIN BOUNDS? - JP Z,RDSEQ3 ; NO, ERROR. - CALL LOGICAL ; CONVERT (BLKNMBR) TO LOGICAL SECTOR (128 BYTE). - CALL TRKSEC1 ; SET THE TRACK AND SECTOR FOR THIS BLOCK #. - CALL DOREAD ; AND READ IT. - JP SETNREC ; AND SET THE NEXT RECORD TO BE ACCESSED. -; -; READ ERROR OCCURED. SET STATUS AND RETURN. -; -RDSEQ3: JP IOERR1 -; -; WRITE THE NEXT S.EQUENTIAL RECORD. -; -WTSEQ: LD A,#1 ; SET S.EQUENTIAL ACCESS MODE. - LD (MODE),A -WTSEQ1: LD A,#0 ; ALLOW AN ADDITION EMPTY EXTENT TO BE OPENED. - LD (R.DWRTFLG),A - CALL CHKWPRT ; CHECK WRITE PROTECT STATUS. - LD HL,(PARAMS) - CALL CKROF1 ; CHECK FOR READ ONLY FILE, (HL) ALREADY SET TO FCB. - CALL STRDATA ; PUT UPDATED DATA INTO FCB. - LD A,(SAVNREC) ; GET RECORD NUMBER TO WRITE. - CP #128 ; WITHIN RANGE? - JP NC,IOERR1 ; NO, ERROR(?). - CALL COMBLK ; COMPUTE BLOCK NUMBER. - CALL CHKBLK ; CHECK NUMBER. - LD C,#0 ; IS THERE ONE TO WRITE TO? - JP NZ,WTSEQ6 ; YES, GO DO IT. - CALL GETBLOCK ; GET NEXT BLOCK NUMBER WITHIN FCB TO USE. - LD (RELBLOCK),A ; AND SAVE. - LD BC,#0 ; START LOOKING FOR SPACE FROM THE START - OR A ; IF NONE ALLOCATED AS YET. - JP Z,WTSEQ2 - LD C,A ; EXTRACT PREVIOUS BLOCK NUMBER FROM FCB - DEC BC ; SO WE CAN BE CLOSEST TO IT. - CALL EXTBLK - LD B,H - LD C,L -WTSEQ2: CALL FNDSPACE ; FIND THE NEXT EMPTY BLOCK NEAREST NUMBER (BC). - LD A,L ; CHECK FOR A ZERO NUMBER. - OR H - JP NZ,WTSEQ3 - LD A,#2 ; NO MORE SPACE? - JP SETSTAT -WTSEQ3: LD (BLKNMBR),HL ; SAVE BLOCK NUMBER TO ACCESS. - EX DE,HL ; PUT BLOCK NUMBER INTO (DE). - LD HL,(PARAMS) ; NOW WE MUST UPDATE THE FCB FOR THIS - LD BC,#16 ; NEWLY ALLOCATED BLOCK. - ADD HL,BC - LD A,(BIGDISK) ; 8 OR 16 BIT BLOCK NUMBERS? - OR A - LD A,(RELBLOCK) ; (* UPDATE THIS ENTRY *) - JP Z,WTSEQ4 ; ZERO MEANS 16 BIT ONES. - CALL ADDA2HL ; (HL)=(HL)+(A) - LD (HL),E ; STORE NEW BLOCK NUMBER. - JP WTSEQ5 -WTSEQ4: LD C,A ; COMPUTE SPOT IN THIS 16 BIT TABLE. - LD B,#0 - ADD HL,BC - ADD HL,BC - LD (HL),E ; STUFF BLOCK NUMBER (DE) THERE. - INC HL - LD (HL),D -WTSEQ5: LD C,#2 ; SET (C) TO INDICATE WRITING TO UN-USED DISK SPACE. -WTSEQ6: LD A,(STATUS) ; ARE WE OK SO FAR? - OR A - RET NZ - PUSH BC ; YES, SAVE WRITE FLAG FOR BIOS (REGISTER C). - CALL LOGICAL ; CONVERT (BLKNMBR) OVER TO LOICAL SECTORS. - LD A,(MODE) ; GET ACCESS MODE FLAG (1=S.EQUENTIAL, - DEC A ; 0=RANDOM, 2=SPECIAL?). - DEC A - JP NZ,WTSEQ9 -; -; SPECIAL RANDOM I/O FROM FUNCTION #40. MAYBE FOR M/PM, BUT THE -; CURRENT BLOCK, IF IT HAS NOT BEEN WRITTEN TO, WILL BE ZEROED -; OUT AND THEN WRITTEN (REASON?). -; - POP BC - PUSH BC - LD A,C ; GET WRITE STATUS FLAG (2=WRITING UNUSED SPACE). - DEC A - DEC A - JP NZ,WTSEQ9 - PUSH HL - LD HL,(DIRBUF) ; ZERO OUT THE DIRECTORY BUFFER. - LD D,A ; NOTE THAT (A) IS ZERO HERE. -WTSEQ7: LD (HL),A - INC HL - INC D ; DO 128 BYTES. - JP P,WTSEQ7 - CALL DIRDMA ; TELL THE BIOS THE DMA ADDRESS FOR DIRECTORY ACCESS. - LD HL,(LOGSECT) ; GET SECTOR THAT STARTS CURRENT BLOCK. - LD C,#2 ; SET 'WRITING TO UNUSED SPACE' FLAG. -WTSEQ8: LD (BLKNMBR),HL ; SAVE SECTOR TO WRITE. - PUSH BC - CALL TRKSEC1 ; DETERMINE ITS TRACK AND SECTOR NUMBERS. - POP BC - CALL DOWRITE ; NOW WRITE OUT 128 BYTES OF ZEROS. - LD HL,(BLKNMBR) ; GET SECTOR NUMBER. - LD C,#0 ; SET NORMAL WRITE FLAG. - LD A,(BLKMASK) ; DETERMINE IF WE HAVE WRITTEN THE ENTIRE - LD B,A ; PHYSICAL BLOCK. - AND L - CP B - INC HL ; PREPARE FOR THE NEXT ONE. - JP NZ,WTSEQ8 ; CONTINUE UNTIL (BLKMASK+1) SECTORS WRITTEN. - POP HL ; RESET NEXT SECTOR NUMBER. - LD (BLKNMBR),HL - CALL DEFDMA ; AND RESET DMA ADDRESS. -; -; NORMAL DISK WRITE. SET THE DESIRED TRACK AND SECTOR THEN -; DO THE ACTUAL WRITE. -; -WTSEQ9: CALL TRKSEC1 ; DETERMINE TRACK AND SECTOR FOR THIS WRITE. - POP BC ; GET WRITE STATUS FLAG. - PUSH BC - CALL DOWRITE ; AND WRITE THIS OUT. - POP BC - LD A,(SAVNREC) ; GET NUMBER OF RECORDS IN FILE. - LD HL,#SAVNXT ; GET LAST RECORD WRITTEN. - CP (HL) - JP C,WTSEQ10 - LD (HL),A ; WE HAVE TO UPDATE RECORD COUNT. - INC (HL) - LD C,#2 -; -;* THIS AREA HAS BEEN PATCHED TO CORRECT DISK UPDATE PROBLEM -;* WHEN USING BLOCKING AND DE-BLOCKING IN THE BIOS. -; -WTSEQ10:NOP ; WAS 'DCR C' - NOP ; WAS 'DCR C' - LD HL,#0 ; WAS 'JNZ WTSEQ99' -; -; * END OF PATCH. -; - PUSH AF - CALL GETS2 ; SET 'EXTENT WRITTEN TO' FLAG. - AND #0x7F ; (* CLEAR BIT 7 *) - LD (HL),A - POP AF ; GET RECORD COUNT FOR THIS EXTENT. -WTSEQ99:CP #127 ; IS IT FULL? - JP NZ,WTSEQ12 - LD A,(MODE) ; YES, ARE WE IN S.EQUENTIAL MODE? - CP #1 - JP NZ,WTSEQ12 - CALL SETNREC ; YES, SET NEXT RECORD NUMBER. - CALL GETNEXT ; AND GET NEXT EMPTY SPACE IN DIRECTORY. - LD HL,#STATUS ; OK? - LD A,(HL) - OR A - JP NZ,WTSEQ11 - DEC A ; YES, SET RECORD COUNT TO -1. - LD (SAVNREC),A -WTSEQ11:LD (HL),#0 ; CLEAR STATUS. -WTSEQ12:JP SETNREC ; SET NEXT RECORD TO ACCESS. -; -; FOR RANDOM I/O, SET THE FCB FOR THE DESIRED RECORD NUMBER -; BASED ON THE 'R0,R1,R2' BYTES. THESE BYTES IN THE FCB ARE -; USED AS FOLLOWS: -; -; FCB+35 FCB+34 FCB+33 -; | 'R-2' | 'R-1' | 'R-0' | -; |7 0 | 7 0 | 7 0| -; |0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0| -; | OVERFLOW | | EXTRA | EXTENT | RECORD # | -; | ______________| |_EXTENT|__NUMBER___|_____________| -; ALSO 'S2' -; -; ON ENTRY, REGISTER (C) CONTAINS 0FFH IF THIS IS A READ -; AND THUS WE CAN NOT ACCESS UNWRITTEN DISK SPACE. OTHERWISE, -; ANOTHER EXTENT WILL BE OPENED (FOR WRITING) IF R.EQUIRED. -; -POSITION: - XOR A ; SET RANDOM I/O FLAG. - LD (MODE),A -; -; SPECIAL ENTRY (FUNCTION #40). M/PM ? -; -POSITN1:PUSH BC ; SAVE READ/WRITE FLAG. - LD HL,(PARAMS) ; GET ADDRESS OF FCB. - EX DE,HL - LD HL,#33 ; NOW GET BYTE 'R0'. - ADD HL,DE - LD A,(HL) - AND #0x7F ; KEEP BITS 0-6 FOR THE RECORD NUMBER TO ACCESS. - PUSH AF - LD A,(HL) ; NOW GET BIT 7 OF 'R0' AND BITS 0-3 OF 'R1'. - RLA - INC HL - LD A,(HL) - RLA - AND #0x1F ; AND SAVE THIS IN BITS 0-4 OF (C). - LD C,A ; THIS IS THE EXTENT BYTE. - LD A,(HL) ; NOW GET THE EXTRA EXTENT BYTE. - RRA - RRA - RRA - RRA - AND #0x0F - LD B,A ; AND SAVE IT IN (B). - POP AF ; GET RECORD NUMBER BACK TO (A). - INC HL ; CHECK OVERFLOW BYTE 'R2'. - LD L,(HL) - INC L - DEC L - LD L,#6 ; PREPARE FOR ERROR. - JP NZ,POSITN5 ; OUT OF DISK SPACE ERROR. - LD HL,#32 ; STORE RECORD NUMBER INTO FCB. - ADD HL,DE - LD (HL),A - LD HL,#12 ; AND NOW CHECK THE EXTENT BYTE. - ADD HL,DE - LD A,C - SUB (HL) ; SAME EXTENT AS BEFORE? - JP NZ,POSITN2 - LD HL,#14 ; YES, CHECK EXTRA EXTENT BYTE 'S2' ALSO. - ADD HL,DE - LD A,B - SUB (HL) - AND #0x7F - JP Z,POSITN3 ; SAME, WE ARE ALMOST DONE THEN. -; -; GET HERE WHEN ANOTHER EXTENT IS R.EQUIRED. -; -POSITN2:PUSH BC - PUSH DE - CALL CLOSEIT ; CLOSE CURRENT EXTENT. - POP DE - POP BC - LD L,#3 ; PREPARE FOR ERROR. - LD A,(STATUS) - INC A - JP Z,POSITN4 ; CLOSE ERROR. - LD HL,#12 ; PUT DESIRED EXTENT INTO FCB NOW. - ADD HL,DE - LD (HL),C - LD HL,#14 ; AND STORE EXTRA EXTENT BYTE 'S2'. - ADD HL,DE - LD (HL),B - CALL OPENIT ; TRY AND GET THIS EXTENT. - LD A,(STATUS) ; WAS IT THERE? - INC A - JP NZ,POSITN3 - POP BC ; NO. CAN WE CREATE A NEW ONE (WRITING?). - PUSH BC - LD L,#4 ; PREPARE FOR ERROR. - INC C - JP Z,POSITN4 ; NOPE, READING UNWRITTEN SPACE ERROR. - CALL GETEMPTY ; YES WE CAN, TRY TO FIND SPACE. - LD L,#5 ; PREPARE FOR ERROR. - LD A,(STATUS) - INC A - JP Z,POSITN4 ; OUT OF SPACE? -; -; NORMAL RETURN LOCATION. CLEAR ERROR CODE AND RETURN. -; -POSITN3:POP BC ; RESTORE STACK. - XOR A ; AND CLEAR ERROR CODE BYTE. - JP SETSTAT -; -; ERROR. SET THE 'S2' BYTE TO INDICATE THIS (WHY?). -; -POSITN4:PUSH HL - CALL GETS2 - LD (HL),#0x0C0 - POP HL -; -; RETURN WITH ERROR CODE (PRESENTLY IN L). -; -POSITN5:POP BC - LD A,L ; GET ERROR CODE. - LD (STATUS),A - JP SETS2B7 -; -; READ A RANDOM RECORD. -; -READRAN:LD C,#0x0FF ; SET 'READ' STATUS. - CALL POSITION ; POSITION THE FILE TO PROPER RECORD. - CALL Z,RDSEQ1 ; AND READ IT AS USUAL (IF NO ERRORS). - RET -; -; WRITE TO A RANDOM RECORD. -; -WRITERAN: - LD C,#0 ; SET 'WRITING' FLAG. - CALL POSITION ; POSITION THE FILE TO PROPER RECORD. - CALL Z,WTSEQ1 ; AND WRITE AS USUAL (IF NO ERRORS). - RET -; -; COMPUTE THE RANDOM RECORD NUMBER. ENTER WITH (HL) POINTING -; TO A FCB AN (DE) CONTAINS A RELATIVE LOCATION OF A RECORD -; NUMBER. ON EXIT, (C) CONTAINS THE 'R0' BYTE, (B) THE 'R1' -; BYTE, AND (A) THE 'R2' BYTE. -; -; ON RETURN, THE ZERO FLAG IS SET IF THE RECORD IS WITHIN -; BOUNDS. OTHERWISE, AN OVERFLOW OCCURED. -; -COMPRAND: - EX DE,HL ; SAVE FCB POINTER IN (DE). - ADD HL,DE ; COMPUTE RELATIVE POSITION OF RECORD #. - LD C,(HL) ; GET RECORD NUMBER INTO (BC). - LD B,#0 - LD HL,#12 ; NOW GET EXTENT. - ADD HL,DE - LD A,(HL) ; COMPUTE (BC)=(RECORD #)+(EXTENT)*128. - RRCA ; MOVE LOWER BIT INTO BIT 7. - AND #0x80 ; AND IGNORE ALL OTHER BITS. - ADD A,C ; ADD TO OUR RECORD NUMBER. - LD C,A - LD A,#0 ; TAKE CARE OF ANY CARRY. - ADC A,B - LD B,A - LD A,(HL) ; NOW GET THE UPPER BITS OF EXTENT INTO - RRCA ; BIT POSITIONS 0-3. - AND #0x0F ; AND IGNORE ALL OTHERS. - ADD A,B ; ADD THIS IN TO 'R1' BYTE. - LD B,A - LD HL,#14 ; GET THE 'S2' BYTE (EXTRA EXTENT). - ADD HL,DE - LD A,(HL) - ADD A,A ; AND SHIFT IT LEFT 4 BITS (BITS 4-7). - ADD A,A - ADD A,A - ADD A,A - PUSH AF ; SAVE CARRY FLAG (BIT 0 OF FLAG BYTE). - ADD A,B ; NOW ADD EXTRA EXTENT INTO 'R1'. - LD B,A - PUSH AF ; AND SAVE CARRY (OVERFLOW BYTE 'R2'). - POP HL ; BIT 0 OF (L) IS THE OVERFLOW INDICATOR. - LD A,L - POP HL ; AND SAME FOR FIRST CARRY FLAG. - OR L ; EITHER ONE OF THESE SET? - AND #1 ; ONLY CHECK THE CARRY FLAGS. - RET -; -; ROUTINE TO SETUP THE FCB (BYTES 'R0', 'R1', 'R2') TO -; REFLECT THE LAST RECORD USED FOR A RANDOM (OR OTHER) FILE. -; THIS READS THE DIRECTORY AND LOOKS AT ALL EXTENTS COMPUTING -; THE LARGERST RECORD NUMBER FOR EACH AND KEEPING THE MAXIMUM -; VALUE ONLY. THEN 'R0', 'R1', AND 'R2' WILL REFLECT THIS -; MAXIMUM RECORD NUMBER. THIS IS USED TO COMPUTE THE SPACE USED -; BY A RANDOM FILE. -; -RANSIZE:LD C,#12 ; LOOK THRU DIRECTORY FOR FIRST ENTRY WITH - CALL FINDFST ; THIS NAME. - LD HL,(PARAMS) ; ZERO OUT THE 'R0, R1, R2' BYTES. - LD DE,#33 - ADD HL,DE - PUSH HL - LD (HL),D ; NOTE THAT (D)=0. - INC HL - LD (HL),D - INC HL - LD (HL),D -RANSIZ1:CALL CKFILPOS ; IS THERE AN EXTENT TO PROCESS? - JP Z,RANSIZ3 ; NO, WE ARE DONE. - CALL FCB2HL ; SET (HL) POINTING TO PROPER FCB IN DIR. - LD DE,#15 ; POINT TO LAST RECORD IN EXTENT. - CALL COMPRAND ; AND COMPUTE RANDOM PARAMETERS. - POP HL - PUSH HL ; NOW CHECK THESE VALUES AGAINST THOSE - LD E,A ; ALREADY IN FCB. - LD A,C ; THE CARRY FLAG WILL BE SET IF THOSE - SUB (HL) ; IN THE FCB REPRESENT A LARGER SIZE THAN - INC HL ; THIS EXTENT DOES. - LD A,B - SBC A,(HL) - INC HL - LD A,E - SBC A,(HL) - JP C,RANSIZ2 - LD (HL),E ; WE FOUND A LARGER (IN SIZE) EXTENT. - DEC HL ; STUFF THESE VALUES INTO FCB. - LD (HL),B - DEC HL - LD (HL),C -RANSIZ2:CALL FINDNXT ; NOW GET THE NEXT EXTENT. - JP RANSIZ1 ; CONTINUE TIL ALL DONE. -RANSIZ3:POP HL ; WE ARE DONE, RESTORE THE STACK AND - RET ; RETURN. -; -; FUNCTION TO RETURN THE RANDOM RECORD POSITION OF A GIVEN -; FILE WHICH HAS BEEN READ IN S.EQUENTIAL MODE UP TO NOW. -; -SETRAN: LD HL,(PARAMS) ; POINT TO FCB. - LD DE,#32 ; AND TO LAST USED RECORD. - CALL COMPRAND ; COMPUTE RANDOM POSITION. - LD HL,#33 ; NOW STUFF THESE VALUES INTO FCB. - ADD HL,DE - LD (HL),C ; MOVE 'R0'. - INC HL - LD (HL),B ; AND 'R1'. - INC HL - LD (HL),A ; AND LASTLY 'R2'. - RET -; -; THIS ROUTINE SELECT THE DRIVE SPECIFIED IN (ACTIVE) AND -; UPDATE THE LOGIN VECTOR AND BITMAP TABLE IF THIS DRIVE WAS -; NOT ALREADY ACTIVE. -; -LOGINDRV: - LD HL,(LOGIN) ; GET THE LOGIN VECTOR. - LD A,(ACTIVE) ; GET THE DEFAULT DRIVE. - LD C,A - CALL SHIFTR ; POSITION ACTIVE BIT FOR THIS DRIVE - PUSH HL ; INTO BIT 0. - EX DE,HL - CALL SELECT ; SELECT THIS DRIVE. - POP HL - CALL Z,SLCTERR ; VALID DRIVE? - LD A,L ; IS THIS A NEWLY ACTIVATED DRIVE? - RRA - RET C - LD HL,(LOGIN) ; YES, UPDATE THE LOGIN VECTOR. - LD C,L - LD B,H - CALL SETBIT - LD (LOGIN),HL ; AND SAVE. - JP BITMAP ; NOW UPDATE THE BITMAP. -; -; FUNCTION TO SET THE ACTIVE DISK NUMBER. -; -SETDSK: LD A,(EPARAM) ; GET PARAMETER PASSED AND SEE IF THIS - LD HL,#ACTIVE ; REPRESENTS A CHANGE IN DRIVES. - CP (HL) - RET Z - LD (HL),A ; YES IT DOES, LOG IT IN. - JP LOGINDRV -; -; THIS IS THE 'AUTO DISK SELECT' ROUTINE. THE FIRSST BYTE -; OF THE FCB IS EXAMINED FOR A DRIVE SPECIFICATION. IF NON -; ZERO THEN THE DRIVE WILL BE SELECTED AND LOGED IN. -; -AUTOSEL:LD A,#0x0FF ; SAY 'AUTO-SELECT ACTIVATED'. - LD (AUTO),A - LD HL,(PARAMS) ; GET DRIVE SPECIFIED. - LD A,(HL) - AND #0x1F ; LOOK AT LOWER 5 BITS. - DEC A ; ADJUST FOR (1=A, 2=B) ETC. - LD (EPARAM),A ; AND SAVE FOR THE SELECT ROUTINE. - CP #0x1E ; CHECK FOR 'NO CHANGE' CONDITION. - JP NC,AUTOSL1 ; YES, DON'T CHANGE. - LD A,(ACTIVE) ; WE MUST CHANGE, SAVE CURRENTLY ACTIVE - LD (OLDDRV),A ; DRIVE. - LD A,(HL) ; AND SAVE FIRST BYTE OF FCB ALSO. - LD (AUTOFLAG),A ; THIS MUST BE NON-ZERO. - AND #0x0E0 ; WHATS THIS FOR (BITS 6,7 ARE USED FOR - LD (HL),A ; SOMETHING)? - CALL SETDSK ; SELECT AND LOG IN THIS DRIVE. -AUTOSL1:LD A,(USERNO) ; MOVE USER NUMBER INTO FCB. - LD HL,(PARAMS) ; (* UPPER HALF OF FIRST BYTE *) - OR (HL) - LD (HL),A - RET ; AND RETURN (ALL DONE). -; -; FUNCTION TO RETURN THE CURRENT CP/M VERSION NUMBER. -; -GETVER: LD A,#0x022 ; VERSION 2.2 - JP SETSTAT -; -; FUNCTION TO RESET THE DISK SYSTEM. -; -RSTDSK: LD HL,#0 ; CLEAR WRITE PROTECT STATUS AND LOG - LD (WRTPRT),HL ; IN VECTOR. - LD (LOGIN),HL - XOR A ; SELECT DRIVE 'A'. - LD (ACTIVE),A - LD HL,#TBUFF ; SETUP DEFAULT DMA ADDRESS. - LD (USERDMA),HL - CALL DEFDMA - JP LOGINDRV ; NOW LOG IN DRIVE 'A'. -; -; FUNCTION TO OPEN A SPECIFIED FILE. -; -OPENFIL:CALL CLEARS2 ; CLEAR 'S2' BYTE. - CALL AUTOSEL ; SELECT PROPER DISK. - JP OPENIT ; AND OPEN THE FILE. -; -; FUNCTION TO CLOSE A SPECIFIED FILE. -; -CLOSEFIL: - CALL AUTOSEL ; SELECT PROPER DISK. - JP CLOSEIT ; AND CLOSE THE FILE. -; -; FUNCTION TO RETURN THE FIRST OCCURENCE OF A SPECIFIED FILE -; NAME. IF THE FIRST BYTE OF THE FCB IS '?' THEN THE NAME WILL -; NOT BE CHECKED (GET THE FIRST ENTRY NO MATTER WHAT). -; -GETFST: LD C,#0 ; PREPARE FOR SPECIAL SEARCH. - EX DE,HL - LD A,(HL) ; IS FIRST BYTE A '?'? - CP #QUESTION - JP Z,GETFST1 ; YES, JUST GET VERY FIRST ENTRY (ZERO LENGTH MATCH). - CALL SETEXT ; GET THE EXTENSION BYTE FROM FCB. - LD A,(HL) ; IS IT '?'? IF YES, THEN WE WANT - CP #QUESTION ; AN ENTRY WITH A SPECIFIC 'S2' BYTE. - CALL NZ,CLEARS2 ; OTHERWISE, LOOK FOR A ZERO 'S2' BYTE. - CALL AUTOSEL ; SELECT PROPER DRIVE. - LD C,#15 ; COMPARE BYTES 0-14 IN FCB (12&13 EXCLUDED). -GETFST1:CALL FINDFST ; FIND AN ENTRY AND THEN MOVE IT INTO - JP MOVEDIR ; THE USERS DMA SPACE. -; -; FUNCTION TO RETURN THE NEXT OCCURENCE OF A FILE NAME. -; -GETNXT: LD HL,(SAVEFCB) ; RESTORE POINTERS. NOTE THAT NO - LD (PARAMS),HL ; OTHER .DBOS CALLS ARE ALLOWED. - CALL AUTOSEL ; NO ERROR WILL BE RETURNED, BUT THE - CALL FINDNXT ; RESULTS WILL BE WRONG. - JP MOVEDIR -; -; FUNCTION TO DELETE A FILE BY NAME. -; -DELFILE:CALL AUTOSEL ; SELECT PROPER DRIVE. - CALL ERAFILE ; ERASE THE FILE. - JP STSTATUS ; SET STATUS AND RETURN. -; -; FUNCTION TO EXECUTE A S.EQUENTIAL READ OF THE SPECIFIED -; RECORD NUMBER. -; -READSEQ:CALL AUTOSEL ; SELECT PROPER DRIVE THEN READ. - JP RDSEQ -; -; FUNCTION TO WRITE THE NET S.EQUENTIAL RECORD. -; -WRTSEQ: CALL AUTOSEL ; SELECT PROPER DRIVE THEN WRITE. - JP WTSEQ -; -; CREATE A FILE FUNCTION. -; -FCREATE:CALL CLEARS2 ; CLEAR THE 'S2' BYTE ON ALL CREATES. - CALL AUTOSEL ; SELECT PROPER DRIVE AND GET THE NEXT - JP GETEMPTY ; EMPTY DIRECTORY SPACE. -; -; FUNCTION TO RENAME A FILE. -; -RENFILE:CALL AUTOSEL ; SELECT PROPER DRIVE AND THEN SWITCH - CALL CHGNAMES ; FILE NAMES. - JP STSTATUS -; -; FUNCTION TO RETURN THE LOGIN VECTOR. -; -GETLOG: LD HL,(LOGIN) - JP GETPRM1 -; -; FUNCTION TO RETURN THE CURRENT DISK ASSIGNMENT. -; -GETCRNT:LD A,(ACTIVE) - JP SETSTAT -; -; FUNCTION TO SET THE DMA ADDRESS. -; -PUTDMA: EX DE,HL - LD (USERDMA),HL ; SAVE IN OUR SPACE AND THEN GET TO - JP DEFDMA ; THE BIOS WITH THIS ALSO. -; -; FUNCTION TO RETURN THE ALLOCATION VECTOR. -; -GETALOC:LD HL,(ALOCVECT) - JP GETPRM1 -; -; FUNCTION TO RETURN THE READ-ONLY STATUS VECTOR. -; -GETROV: LD HL,(WRTPRT) - JP GETPRM1 -; -; FUNCTION TO SET THE FILE ATTRIBUTES (READ-ONLY, SYSTEM). -; -SETATTR:CALL AUTOSEL ; SELECT PROPER DRIVE THEN SAVE ATTRIBUTES. - CALL SAVEATTR - JP STSTATUS -; -; FUNCTION TO RETURN THE ADDRESS OF THE DISK PARAMETER BLOCK -; FOR THE CURRENT DRIVE. -; -GETPARM:LD HL,(DISKPB) -GETPRM1:LD (STATUS),HL - RET -; -; FUNCTION TO GET OR SET THE USER NUMBER. IF (E) WAS (FF) -; THEN THIS IS A R.EQUEST TO RETURN THE CURRENT USER NUMBER. -; ELSE SET THE USER NUMBER FROM (E). -; -GETUSER:LD A,(EPARAM) ; GET PARAMETER. - CP #0x0FF ; GET USER NUMBER? - JP NZ,SETUSER - LD A,(USERNO) ; YES, JUST DO IT. - JP SETSTAT -SETUSER:AND #0x1F ; NO, WE SHOULD SET IT INSTEAD. KEEP LOW - LD (USERNO),A ; BITS (0-4) ONLY. - RET -; -; FUNCTION TO READ A RANDOM RECORD FROM A FILE. -; -RDRANDOM: - CALL AUTOSEL ; SELECT PROPER DRIVE AND READ. - JP READRAN -; -; FUNCTION TO COMPUTE THE FILE SIZE FOR RANDOM FILES. -; -WTRANDOM: - CALL AUTOSEL ; SELECT PROPER DRIVE AND WRITE. - JP WRITERAN -; -; FUNCTION TO COMPUTE THE SIZE OF A RANDOM FILE. -; -FILESIZE: - CALL AUTOSEL ; SELECT PROPER DRIVE AND CHECK FILE LENGTH - JP RANSIZE -; -; FUNCTION #37. THIS ALLOWS A PROGRAM TO LOG OFF ANY DRIVES. -; ON ENTRY, SET (DE) TO CONTAIN A WORD WITH BITS SET FOR THOSE -; DRIVES THAT ARE TO BE LOGGED OFF. THE LOG-IN VECTOR AND THE -; WRITE PROTECT VECTOR WILL BE UPDATED. THIS MUST BE A M/PM -; SPECIAL FUNCTION. -; -LOGOFF: LD HL,(PARAMS) ; GET DRIVES TO LOG OFF. - LD A,L ; FOR EACH BIT THAT IS SET, WE WANT - CPL ; TO CLEAR THAT BIT IN (LOGIN) - LD E,A ; AND (WRTPRT). - LD A,H - CPL - LD HL,(LOGIN) ; RESET THE LOGIN VECTOR. - AND H - LD D,A - LD A,L - AND E - LD E,A - LD HL,(WRTPRT) - EX DE,HL - LD (LOGIN),HL ; AND SAVE. - LD A,L ; NOW DO THE WRITE PROTECT VECTOR. - AND E - LD L,A - LD A,H - AND D - LD H,A - LD (WRTPRT),HL ; AND SAVE. ALL DONE. - RET -; -; GET HERE TO RETURN TO THE USER. -; -GOBACK: LD A,(AUTO) ; WAS AUTO SELECT ACTIVATED? - OR A - JP Z,GOBACK1 - LD HL,(PARAMS) ; YES, BUT WAS A CHANGE MADE? - LD (HL),#0 ; (* RESET FIRST BYTE OF FCB *) - LD A,(AUTOFLAG) - OR A - JP Z,GOBACK1 - LD (HL),A ; YES, RESET FIRST BYTE PROPERLY. - LD A,(OLDDRV) ; AND GET THE OLD DRIVE AND SELECT IT. - LD (EPARAM),A - CALL SETDSK -GOBACK1:LD HL,(USRSTACK) ; RESET THE USERS STACK POINTER. - LD SP,HL - LD HL,(STATUS) ; GET RETURN STATUS. - LD A,L ; FORCE VERSION 1.4 COMPATABILITY. - LD B,H - RET ; AND GO BACK TO USER. -; -; FUNCTION #40. THIS IS A SPECIAL ENTRY TO DO RANDOM I/O. -; FOR THE CASE WHERE WE ARE WRITING TO UNUSED DISK SPACE, THIS -; SPACE WILL BE ZEROED OUT FIRST. THIS MUST BE A M/PM SPECIAL -; PURPOSE FUNCTION, BECAUSE WHY WOULD ANY NORMAL PROGRAM EVEN -; CARE ABOUT THE PREVIOUS CONTENTS OF A SECTOR ABOUT TO BE -; WRITTEN OVER. -; -WTSPECL:CALL AUTOSEL ; SELECT PROPER DRIVE. - LD A,#2 ; USE SPECIAL WRITE MODE. - LD (MODE),A - LD C,#0 ; SET WRITE INDICATOR. - CALL POSITN1 ; POSITION THE FILE. - CALL Z,WTSEQ1 ; AND WRITE (IF NO ERRORS). - RET -; -;************************************************************** -;* -;* BDOS DATA STORAGE POOL. -;* -;************************************************************** -; -EMPTYFCB: - .DB 0x0E5 ; EMPTY DIRECTORY SEGMENT INDICATOR. -WRTPRT: .DW 0 ; WRITE PROTECT STATUS FOR ALL 16 DRIVES. -LOGIN: .DW 0 ; DRIVE ACTIVE WORD (1 BIT PER DRIVE). -USERDMA:.DW 0x80 ; USER'S DMA ADDRESS (DEFAULTS TO 80H). -; -; SCRATCH AREAS FROM PARAMETER BLOCK. -; -SCRATCH1: - .DW 0 ; RELATIVE POSITION WITHIN DIR SEGMENT FOR FILE (0-3). -SCRATCH2: - .DW 0 ; LAST SELECTED TRACK NUMBER. -SCRATCH3: - .DW 0 ; LAST SELECTED SECTOR NUMBER. -; -; DISK STORAGE AREAS FROM PARAMETER BLOCK. -; -DIRBUF: .DW 0 ; ADDRESS OF DIRECTORY BUFFER TO USE. -DISKPB: .DW 0 ; CONTAINS ADDRESS OF DISK PARAMETER BLOCK. -CHKVECT:.DW 0 ; ADDRESS OF CHECK VECTOR. -ALOCVECT: - .DW 0 ; ADDRESS OF ALLOCATION VECTOR (BIT MAP). -; -; PARAMETER BLOCK RETURNED FROM THE BIOS. -; -SECTORS:.DW 0 ; SECTORS PER TRACK FROM BIOS. -BLKSHFT:.DB 0 ; BLOCK SHIFT. -BLKMASK:.DB 0 ; BLOCK MASK. -EXTMASK:.DB 0 ; EXTENT MASK. -DSKSIZE:.DW 0 ; DISK SIZE FROM BIOS (NUMBER OF BLOCKS-1). -DIRSIZE:.DW 0 ; DIRECTORY SIZE. -ALLOC0: .DW 0 ; STORAGE FOR FIRST BYTES OF BIT MAP (DIR SPACE USED). -ALLOC1: .DW 0 -OFFSET: .DW 0 ; FIRST USABLE TRACK NUMBER. -XLATE: .DW 0 ; SECTOR TRANSLATION TABLE ADDRESS. -; -; -CLOSEFLG: - .DB 0 ; CLOSE FLAG (=0FFH IS EXTENT WRITTEN OK). -R.DWRTFLG: - .DB 0 ; READ/WRITE FLAG (0FFH=READ, 0=WRITE). -FNDSTAT:.DB 0 ; FILENAME FOUND STATUS (0=FOUND FIRST ENTRY). -MODE: .DB 0 ; I/O MODE SELECT (0=RANDOM, 1=S.EQUENTIAL, 2=SPECIAL RANDOM). -EPARAM: .DB 0 ; STORAGE FOR REGISTER (E) ON ENTRY TO BDOS. -RELBLOCK: - .DB 0 ; RELATIVE POSITION WITHIN FCB OF BLOCK NUMBER WRITTEN. -COUNTER:.DB 0 ; BYTE COUNTER FOR DIRECTORY NAME SEARCHES. -SAVEFCB:.DW 0,0 ; SAVE SPACE FOR ADDRESS OF FCB (FOR DIRECTORY SEARCHES). -BIGDISK:.DB 0 ; IF =0 THEN DISK IS > 256 BLOCKS LONG. -AUTO: .DB 0 ; IF NON-ZERO, THEN AUTO SELECT ACTIVATED. -OLDDRV: .DB 0 ; ON AUTO SELECT, STORAGE FOR PREVIOUS DRIVE. -AUTOFLAG: - .DB 0 ; IF NON-ZERO, THEN AUTO SELECT CHANGED DRIVES. -SAVNXT: .DB 0 ; STORAGE FOR NEXT RECORD NUMBER TO ACCESS. -SAVEXT: .DB 0 ; STORAGE FOR EXTENT NUMBER OF FILE. -SAVNREC:.DW 0 ; STORAGE FOR NUMBER OF RECORDS IN FILE. -BLKNMBR:.DW 0 ; BLOCK NUMBER (PHYSICAL SECTOR) USED WITHIN A FILE OR LOGICAL SEC -LOGSECT:.DW 0 ; STARTING LOGICAL (128 BYTE) SECTOR OF BLOCK (PHYSICAL SECTOR). -FCBPOS: .DB 0 ; RELATIVE POSITION WITHIN BUFFER FOR FCB OF FILE OF INTEREST. -FILEPOS:.DW 0 ; FILES POSITION WITHIN DIRECTORY (0 TO MAX ENTRIES -1). -; -; DISK DIRECTORY BUFFER CHECKSUM BYTES. ONE FOR EACH OF THE -; 16 POSSIBLE DRIVES. -; -CKSUMTBL: - .DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -; -;************************************************************** -;* -;* B I O S J U M P T A B L E -;* -;************************************************************** -; - -BIOS = BIOSO ;BIOS ORIGIN -; -BOOT = BIOS ;(BOOT) Cold boot entry -WBOOT = BIOS+3 ;Warm boot entry -CONST = BIOS+6 ;Console status -CONIN = BIOS+9 ;Console char in -CONOUT = BIOS+12 ;Console char out -LIST = BIOS+15 ;List char out -PUNCH = BIOS+18 ;Punch char out -READER = BIOS+21 ;Reader char in -HOME = BIOS+24 ;Home disk -SELDSK = BIOS+27 ;Select disk -SETTRK = BIOS+30 ;Set disk track addr -SETSEC = BIOS+33 ;Set disk sector addr -SETDMA = BIOS+36 ;Set DMA buffer addr -READ = BIOS+39 ;Read sector -WRITE = BIOS+42 ;Write sector -SECTRN = BIOS+48 ;Sector translation routine -; -;dwg; .IF ENDFIL -;dwg; .ORG BDOSO+0DFFH -;dwg; .DB 55H -;dwg; .ENDIF - -;dwg; .END - -_bdos_end:: - .area _CODE - .area _CABS diff --git a/doug/src/bdosb01.sym b/doug/src/bdosb01.sym deleted file mode 100755 index 21a81a34..00000000 --- a/doug/src/bdosb01.sym +++ /dev/null @@ -1,136 +0,0 @@ - ASxxxx Assembler V02.00 + NoICE + SDCC mods + Flat24 (Zilog Z80 / Hitachi HD64180), page 1. -bdosb01.s derived from bdosb01.asm -Symbol Table - - .__.ABS.= 0000 G | 6 ACTIVE 0342 R | 6 ADDA2HL 0564 R - 6 ALLOC0 0DCA R | 6 ALLOC1 0DCC R | 6 ALOCVECT 0DBF R - ASCIIA = 0041 | AT = 0040 | 6 AUTO 0DDE R - 6 AUTOFLAG 0DE0 R | 6 AUTOSEL 0C51 R | 6 AUTOSL1 0C75 R - 6 BACKUP 01A4 R | 6 BACKUP1 01AC R | 6 BADSCTR 0009 R - 6 BADSEC 00CA R | 6 BADSEL 00D5 R | 6 BADSLCT 000B R - BASE = 9C00 | 6 BDOSDRV 00C6 R | 6 BDOSERR 00BA R - BDOSO = D800 | 6 BIGDISK 0DDD R | BIOS = E600 - BIOSO = E600 | 6 BITMAP 06A3 R | 6 BITMAP1 06B1 R - 6 BITMAP2 06D2 R | 6 BITMAP3 06F6 R | 6 BLKMASK 0DC4 R - 6 BLKNMBR 0DE5 R | 6 BLKSHFT 0DC3 R | BOOT = E600 - BS = 0008 | CCPO = D000 | 6 CHARBUF 030E R - 6 CHECKDIR 059E R | 6 CHECKSUM 04F7 R | 6 CHGNAM1 0827 R - 6 CHGNAMES 0816 R | 6 CHKBLK 0484 R | 6 CHKCHAR 0114 R - 6 CHKDIR1 05C4 R | 6 CHKNMBR 058C R | 6 CHKROFL 0544 R - 6 CHKSUM1 04FD R | 6 CHKVECT 0DBD R | 6 CHKWPRT 0554 R - 6 CKBITMAP 0635 R | 6 CKBMAP1 0656 R | 6 CKCON1 0142 R - 6 CKCON2 0145 R | 6 CKCONSOL 0123 R | 6 CKFILPOS 05F5 R - 6 CKROF1 0547 R | 6 CKSUMTBL 0DEC R | 6 CLEARS2 0572 R - 6 CLOSEFIL 0CA5 R | 6 CLOSEFLG 0DD2 R | 6 CLOSEIT 08A2 R - 6 CLOSEIT1 08CD R | 6 CLOSEIT2 08DB R | 6 CLOSEIT3 08E1 R - 6 CLOSEIT4 08E8 R | 6 CLOSEIT5 08FD R | 6 CLOSEIT6 0917 R - 6 CLOSEIT7 091F R | CNTRLC = 0003 | CNTRLE = 0005 - CNTRLP = 0010 | CNTRLR = 0012 | CNTRLS = 0013 - CNTRLU = 0015 | CNTRLX = 0018 | CNTRLZ = 001A - 6 COMBLK 0477 R | 6 COMPRAND 0BA5 R | CONIN = E609 - CONOUT = E60C | CONST = E606 | 6 COUNTER 0DD8 R - CR = 000D | 6 CURPOS 030C R | 6 DE2HL 034F R - 6 DE2HL1 0350 R | 6 DEFDMA 05DA R | DEL = 007F - 6 DELFILE 0CD7 R | 6 DIRBUF 0DB9 R | 6 DIRC1 02E0 R - 6 DIRCIO 02D4 R | 6 DIRDMA 05E0 R | 6 DIRDMA1 05E3 R - 6 DIRREAD 05D4 R | 6 DIRSIZE 0DC8 R | 6 DIRWRITE 05C6 R - 6 DISKPB 0DBB R | 6 DISKRO 00E1 R | DOLLAR = 0024 - 6 DOREAD 03B2 R | 6 DOWRITE 03B8 R | 6 DSKSIZE 0DC6 R - 6 EMPTYFCB 0DAC R | ENDFIL = 0001 | ENTRY = 0005 - 6 EPARAM 0DD6 R | 6 ERAFIL1 07A4 R | 6 ERAFILE 079C R - 6 ERROR1 0099 R | 6 ERROR2 00A5 R | 6 ERROR3 00AB R - 6 ERROR4 00B1 R | 6 ERROR5 00B4 R | 6 EXTBLK 045E R - 6 EXTBLK1 0471 R | 6 EXTMASK 0DC5 R | 6 FBASE 0006 R - 6 FBASE1 0011 R | 6 FCB2HL 055E R | 6 FCBPOS 0DE9 R - 6 FCBSET 07FD R | 6 FCREATE 0CEC R | FF = 000C - 6 FILEPOS 0DEA R | 6 FILERO 00DC R | 6 FILESIZE 0D4D R - 6 FINDFST 0718 R | 6 FINDNXT 072D R | 6 FNDNXT1 074A R - 6 FNDNXT2 0753 R | 6 FNDNXT3 0773 R | 6 FNDNXT4 077C R - 6 FNDNXT5 0783 R | 6 FNDNXT6 0794 R | 6 FNDSPA1 07C0 R - 6 FNDSPA2 07D1 R | 6 FNDSPA3 07EC R | 6 FNDSPA4 07F4 R - 6 FNDSPACE 07BE R | 6 FNDSTAT 0DD4 R | 6 FUNCTNS 0047 R - 6 GETALOC 0D11 R | 6 GETBLK1 0445 R | 6 GETBLK2 0453 R - 6 GETBLK3 045C R | 6 GETBLOCK 043E R | 6 GETCHAR 00FB R - 6 GETCON 02C8 R | 6 GETCRNT 0D04 R | 6 GETCSTS 02FE R - 6 GETECHO 0106 R | 6 GETEMPTY 0924 R | 6 GETFST 0CAB R - 6 GETFST1 0CC2 R | 6 GETIOB 02ED R | 6 GETLOG 0CFE R - 6 GETMT1 0946 R | 6 GETNEXT 095A R | 6 GETNXT 0CC8 R - 6 GETPARM 0D26 R | 6 GETPRM1 0D29 R | 6 GETRDR 02CE R - 6 GETROV 0D17 R | 6 GETS2 0569 R | 6 GETUSER 0D2D R - 6 GETVER 0C7E R | 6 GETWPRT 051E R | 6 GOBACK 0D74 R - 6 GOBACK1 0D91 R | 6 GTNEXT1 0983 R | 6 GTNEXT2 098E R - 6 GTNEXT3 09AC R | 6 GTNEXT4 09AF R | 6 GTNEXT5 09B6 R - HOME = E618 | 6 HOMEDRV 03A1 R | IOBYTE = 0003 - 6 IOERR1 0305 R | 6 IORET 03BB R | 6 JUMPHL 034A R - LF = 000A | LIST = E60F | 6 LOGICAL 048A R - 6 LOGICL1 0490 R | 6 LOGIN 0DAF R | 6 LOGINDRV 0C21 R - 6 LOGOFF 0D53 R | 6 LOGSECT 0DE7 R | 6 MODE 0DD5 R - 6 MOREFLS 057F R | 6 MOVEDIR 05E9 R | 6 MOVEWORD 0894 R - 6 NEWLINE 01B1 R | 6 NEWLN1 01B9 R | NFUNCTS = 0029 - NK = 003B | 6 NXENT1 0619 R | 6 NXENT2 0620 R - 6 NXENTRY 0605 R | 6 OFFSET 0DCE R | 6 OLDDRV 0DDF R - 6 OPENFIL 0C9C R | 6 OPENIT 0851 R | 6 OPENIT1 085A R - 6 OPENIT2 088B R | 6 OUTCHAR 0148 R | 6 OUTCHR1 0162 R - 6 OUTCHR2 0179 R | 6 OUTCON 0190 R | 6 OUTCON1 0196 R - 6 OUTCRLF 01C9 R | 6 OUTFLAG 030A R | 6 PARAMS 0343 R - 6 POSITION 0B03 R | 6 POSITN1 0B07 R | 6 POSITN2 0B47 R - 6 POSITN3 0B7F R | 6 POSITN4 0B84 R | 6 POSITN5 0B8B R - POUND = 0023 | 6 PRTERR 00E5 R | 6 PRTFLAG 030D R - 6 PRTMESG 01D3 R | 6 PRTSTR 02F8 R | PUNCH = E612 - 6 PUTDMA 0D0A R | QUESTION= 003F | 6 R.DBUF1 01EF R - 6 R.DBUF10 0270 R | 6 R.DBUF11 0278 R | 6 R.DBUF12 028A R - 6 R.DBUF13 0299 R | 6 R.DBUF14 02A6 R | 6 R.DBUF15 02A9 R - 6 R.DBUF16 02BD R | 6 R.DBUF17 02C1 R | 6 R.DBUF2 01F1 R - 6 R.DBUF3 0216 R | 6 R.DBUF4 0226 R | 6 R.DBUF5 0237 R - 6 R.DBUF6 0248 R | 6 R.DBUF7 024E R | 6 R.DBUF8 025F R - 6 R.DBUF9 026B R | 6 R.DBUFF 01E1 R | 6 R.DWRTFL 0DD3 R - 6 RANSIZ1 0BE4 R | 6 RANSIZ2 0C06 R | 6 RANSIZ3 0C0C R - 6 RANSIZE 0BD2 R | 6 RDRANDOM 0D41 R | 6 RDSEQ 09BC R - 6 RDSEQ1 09C1 R | 6 RDSEQ2 09E6 R | 6 RDSEQ3 09FB R - READ = E627 | READER = E615 | 6 READRAN 0B93 R - 6 READSEQ 0CE0 R | 6 RELBLOCK 0DD7 R | 6 RENFILE 0CF5 R - 6 RODISK 000D R | 6 ROFILE 000F R | 6 RSTDSK 0C83 R - 6 RTN 0304 R | 6 SAMEXT 0707 R | 6 SAVATR1 0840 R - 6 SAVEATTR 083B R | 6 SAVEFCB 0DD9 R | 6 SAVEXT 0DE2 R - 6 SAVNREC 0DE3 R | 6 SAVNXT 0DE1 R | 6 SCRATCH1 0DB3 R - 6 SCRATCH2 0DB5 R | 6 SCRATCH3 0DB7 R | 6 SECTORS 0DC1 R - SECTRN = E630 | SELDSK = E61B | 6 SELECT 0359 R - 6 SELECT1 039D R | 6 SETATTR 0D1D R | 6 SETBIT 050B R - 6 SETDIR 059C R | SETDMA = E624 | 6 SETDSK 0C45 R - 6 SETEXT 04A6 R | 6 SETFILE 066B R | 6 SETFL1 0675 R - 6 SETFL2 0688 R | 6 SETFL3 068E R | 6 SETFL4 069D R - 6 SETHLDE 04AE R | 6 SETIOB 02F3 R | 6 SETNREC 04D2 R - 6 SETRAN 0C0E R | 6 SETS2B7 0578 R | SETSEC = E621 - 6 SETSTAT 0301 R | SETTRK = E61E | 6 SETUSER 0D3B R - 6 SHIFTL 0504 R | 6 SHIFTL1 0505 R | 6 SHIFTR 04EA R - 6 SHIFTR1 04EB R | 6 SHOWIT 017F R | 6 SLCTERR 0347 R - SPACE = 0020 | 6 STARTING 030B R | 6 STATUS 0345 R - 6 STBITMAP 065C R | 6 STBMAP1 0664 R | 6 STFILPOS 05FE R - 6 STKAREA 0341 R | 6 STNREC1 04DE R | 6 STRDATA 04BB R - 6 STSTATUS 0701 R | 6 SUBHL 0595 R | TAB = 0009 - TBASE = 0100 | TBUFF = 0080 | TDRIVE = 0004 - TFCB = 005C | 6 TRKSEC 03C3 R | 6 TRKSEC1 03D1 R - 6 TRKSEC2 03E4 R | 6 TRKSEC3 03FA R | 6 TRKSEC4 040F R - UP = 005E | 6 UPDATE 0801 R | 6 UPDATE1 0810 R - 6 USERDMA 0DB1 R | 6 USERNO 0341 R | 6 USRSTACK 030F R - WBOOT = E603 | WRITE = E62A | 6 WRITERAN 0B9C R - 6 WRTPRT 0DAD R | 6 WRTPRTD 052C R | 6 WRTSEQ 0CE6 R - 6 WTRANDOM 0D47 R | 6 WTSEQ 09FE R | 6 WTSEQ1 0A03 R - 6 WTSEQ10 0AD2 R | 6 WTSEQ11 0AFE R | 6 WTSEQ12 0B00 R - 6 WTSEQ2 0A3B R | 6 WTSEQ3 0A48 R | 6 WTSEQ4 0A64 R - 6 WTSEQ5 0A6C R | 6 WTSEQ6 0A6E R | 6 WTSEQ7 0A8C R - 6 WTSEQ8 0A9A R | 6 WTSEQ9 0ABB R | 6 WTSEQ99 0ADF R - 6 WTSPECL 0D9B R | 6 XLATE 0DD0 R | 0 _bdos 0000 GR - 6 _bdos_en 0DFC GR | 0 _bdos_st 0000 GR - ASxxxx Assembler V02.00 + NoICE + SDCC mods + Flat24 (Zilog Z80 / Hitachi HD64180), page 2. -bdosb01.s derived from bdosb01.asm -Area Table - - 0 _CODE size 0 flags 0 - 1 _DATA size 0 flags 0 - 2 _OVERLAY size 0 flags 0 - 3 _HOME size 0 flags 0 - 4 _GSINIT size 0 flags 0 - 5 _GSFINAL size 0 flags 0 - 6 _BDOSB01 size DFC flags 0 - 7 _CABS size 0 flags 0 diff --git a/doug/src/cbios.lst b/doug/src/cbios.lst deleted file mode 100755 index 869b7cfe..00000000 --- a/doug/src/cbios.lst +++ /dev/null @@ -1,2750 +0,0 @@ - 1 .title cbios.s derived from cbios.asm - 2 .sbttl by Douglas Goodall for N8VEM use '11 - 3 - 4 .module cbios - 5 .optsdcc -mz80 - 6 - 7 ;-------------------------------------------------------- - 8 ; Public variables in this module - 9 ;-------------------------------------------------------- - 10 .globl _cbios - 11 ;-------------------------------------------------------- - 12 ; special function registers - 13 ;-------------------------------------------------------- - 14 ;-------------------------------------------------------- - 15 ; ram data - 16 ;-------------------------------------------------------- - 17 .area _DATA - 18 ;-------------------------------------------------------- - 19 ; overlayable items in ram - 20 ;-------------------------------------------------------- - 21 .area _OVERLAY - 22 ;-------------------------------------------------------- - 23 ; external initialized ram data - 24 ;-------------------------------------------------------- - 25 ;-------------------------------------------------------- - 26 ; global & static initialisations - 27 ;-------------------------------------------------------- - 28 .area _HOME - 29 .area _GSINIT - 30 .area _GSFINAL - 31 .area _GSINIT - 32 ;-------------------------------------------------------- - 33 ; Home - 34 ;-------------------------------------------------------- - 35 .area _HOME - 36 .area _HOME - 37 ;-------------------------------------------------------- - 38 ; code - 39 ;-------------------------------------------------------- - 40 - 41 ; .area _CODE - 42 .area _CBIOS - 43 - 0000 44 _cbios_start:: - 0000 45 _cbios: - 46 - 47 ; CBIOS FOR N8VEM - 48 ; - 49 ; Supports: Floppy, IDE HDD, ATAPI ZIP, RAM & ROM DRIVES, on board 16550, DSKY & VDU CARD - 50 ; - 51 ; BY ANDREW LYNCH, WITH INPUT FROM MANY SOURCES - 52 ; - 53 ; DATA CONSTANTS - 54 ;__________________________________________________________________________________________________ - 0000 55 FALSE = 0 - 0001 56 TRUE = 1 - 57 - 58 ; LIST OF CONDITIONAL ASSEMBLY INSTRUCTIONS - 59 - 0001 60 CONDIDESOFT = TRUE ; IF NO IDE DRIVE, HAS A SIGNIFICANT DELAY ON SOFT BOOT (TRUE) OR QUICK (FALSE) - 0001 61 CONDSHORTMSG = TRUE ; TRUE FOR ORIGINAL WARM BOOT SIGNON, FALSE FOR SHORTER ONE WITH LESS - 0001 62 CONDSUPERSUB = TRUE ; TRUE FOR NO SUPERSUB AUTOEXEC, FALSE TO RUN SUPERSUB AUTOEXEC - 0001 63 CONDABONLY = TRUE ; TRUE FOR ORIGINAL, FALSE TO ONLY HAVE DRIVE A AND B - 64 - 0000 65 CONDUSEVDU = FALSE ; TRUE FOR USE VDU CARD, FALSE TO USE SERIAL PORT (FOR CONSOLE) - 0001 66 CONDUSEFLOPPY = TRUE ; TRUE FOR USE FLOPPY, FALSE FOR NO FLOPPY DRIVE - 0001 67 COND144FLOPPY = TRUE ; TRUE FOR 1.44Mb FLOPPY ON DRIVE G: - 0000 68 CONDUSEATAPI = FALSE ; TRUE FOR USE ZIP DISK, FALSE FOR NO ZIP DISK - 0000 69 CONDUSEDSKY = FALSE ; TRUE FOR USE DSKY, FALSE FOR NO DSKY - 70 - 71 ; POINTERS TO VDU ROUTINES IN HIGH ROM BANK (NOT NEEDED IF NOT USING VDU CARD) - 72 - 0100 73 VDU_INIT = 0x0100 ; VECTOR TO VDU INIT CODE - 0395 74 IS_KBHIT = 0x0395 ; VECTOR TO KB HIT CODE - 039C 75 GET_KEY = 0x039C ; VECTOR TO GET KEY CODE - 011B 76 CHARIN = 0x011B ; VECTOR TO CHARIN CODE - 0CD6 77 PR_OUTCHAR = 0x0CD6 ; VECTOR TO PRINTER CODE - 78 - 79 ; - 003B 80 MSIZE = 59 ;CP/M VERSION MEMORY SIZE IN KILOBYTES - 81 ; - 82 ; "BIAS" IS ADDRESS OFFSET FROM 3400H FOR MEMORY SYSTEMS - 83 ; THAN 16K (REFERRED TO AS "B" THROUGHOUT THE TEXT) - 84 ; - 9C00 85 BIAS = (MSIZE-20)*1024 ; - D000 86 CCP = 0x3400+BIAS ; BASE OF CCP - D806 87 BDOS = CCP+0x806 ; BASE OF BDOS - E600 88 BIOS = CCP+0x1600 ; BASE OF BIOS - 0004 89 CDISK = 4 ; CURRENT DISK NUMBER 0=A,...,15=P - 0003 90 IOBYTE = 3 ; I/O DEFINITION BYTE. - 91 - 00FF 92 END = 0x0FF - 000D 93 CR = 0x0D - 000A 94 LF = 0x0A - 95 - 96 ; TEST PROTOTYPE SPECIFIC HARDWARE IO PORT ADDRESSES AND MEMORY LOCATIONS - 97 - 0068 98 UART = 0x68 ; BASE IO ADDRESS OF UART - 0078 99 MPCL_RAM = 0x78 ; BASE IO ADDRESS OF RAM MEMORY PAGER CONFIGURATION LATCH - 007C 100 MPCL_ROM = 0x7C ; BASE IO ADDRESS OF ROM MEMORY PAGER CONFIGURATION LATCH - 101 - 0A00 102 ROMSTART_CPM= 0x00A00 ; WHERE THE CCP+BDOS+BIOS IS STORED IN ROM - D000 103 RAMTARG_CPM= 0x0D000 ; WHERE THE CCP+BDOS+BIOS STARTS IN RAM (ENTRY POINT) - 2BFF 104 MOVSIZ_CPM= 0x02BFF ; CCP, BDOS - 0800 105 CCPSIZ_CPM= 0x00800 ; CCP 0800h BYTES IN LENGTH - 106 - 107 ; IDE REGISTER IO PORT ; FUNCTION - 0020 108 IDELO = 0x20 ; DATA PORT (LOW BYTE) - 0021 109 IDEERR = 0x21 ; READ: ERROR REGISTER; WRITE: PRECOMP - 0022 110 IDESECTC = 0x22 ; SECTOR COUNT - 0023 111 IDESECTN = 0x23 ; SECTOR NUMBER - 0024 112 IDECYLLO = 0x24 ; CYLINDER LOW - 0025 113 IDECYLHI = 0x25 ; CYLINDER HIGH - 0026 114 IDEHEAD = 0x26 ; DRIVE/HEAD - 0027 115 IDESTTS = 0x27 ; READ: STATUS; WRITE: COMMAND - 0028 116 IDEHI = 0x28 ; DATA PORT (HIGH BYTE) - 002E 117 IDECTRL = 0x2E ; READ: ALTERNATIVE STATUS; WRITE; DEVICE CONTROL - 002F 118 IDEADDR = 0x2F ; DRIVE ADDRESS (READ ONLY) - 0036 119 FMSR = 0x36 ; ADDRESS OF MAIN STATUS REGISTER - 0037 120 FDATA = 0x37 ; FLOPPY DATA REGISTER - 003A 121 FLATCH = 0x3A ; FLOPPY CONFIGURATION LATCH - 003C 122 FDMA = 0x3C ; PSEUDO DMA ADDRESS - 123 ; - 124 ; FDC CONFIGURATION LATCH OUTPUT BIT PATTERNS - 0000 125 MOTOR = 0b00000000 ; BIT PATTERN IN LATCH FOR MOTOR CONTROL (ON) - 0001 126 TERMCN = 0b00000001 ; BIT PATTERN IN LATCH TO WRITE A TC STROBE - 0002 127 RESETL = 0b00000010 ; BIT PATTERN IN LATCH TO RESET ALL BITS - 0004 128 MINI = 0b00000100 ; BIT PATTERN IN LATCH TO SET MINI MODE FDC9229 LOW DENS=1, HIGH DENS=0 - 0020 129 PRECOMP = 0b00100000 ; BIT PATTERN IN LATCH TO SET WRITE PRECOMP 125 NS: - 0040 130 FDDENSITY = 0b01000000 ; BIT PATTERN IN LATCH TO FLOPPY LOW DENSITY (HIGH IS 0) - 0080 131 FDREADY = 0b10000000 ; BIT PATTERN IN LATCH TO FLOPPY READY (P-34): - 132 ; - 133 ; PIO 82C55 I/O IS DECODED TO PORT 60-67 - 0060 134 PORTA = 0x60 ; PORT A - 0061 135 PORTB = 0x61 ; PORT B - 0062 136 PORTC = 0x62 ; PORT C - 0063 137 PIOCONT = 0x63 ; PIO CONTROL PORT - 138 - 139 - 140 ;dwg; .ORG BIOS - 141 - 142 ;__________________________________________________________________________________________________ - 143 ; - 144 ; CP/M JUMP VECTOR TABLE FOR INDIVIDUAL SUBROUTINES - 145 ;__________________________________________________________________________________________________ - 146 ; - 0000 C3r1Bs01 147 JP BOOT ; COLD START - 0003 C3r46s01 148 WBOOTE: JP WBOOT ; WARM START - 0006 C3r9Cs01 149 JP CONST ; CONSOLE STATUS - 0009 C3rA6s01 150 JP CONIN ; CONSOLE CHARACTER IN - 000C C3rB1s01 151 JP CONOUT ; CONSOLE CHARACTER OUT - 000F C3rBCs01 152 JP LIST ; LIST CHARACTER OUT (NULL ROUTINE) - 0012 C3rC0s01 153 JP PUNCH ; PUNCH CHARACTER OUT (NULL ROUTINE) - 0015 C3rC2s01 154 JP READER ; READER CHARACTER OUT (NULL ROUTINE) - 0018 C3rDAs01 155 JP HOME ; MOVE HEAD TO HOME POSITION - 001B C3rC4s01 156 JP SELDSK ; SELECT DISK - 001E C3rDDs01 157 JP SETTRK ; SET TRACK NUMBER - 0021 C3rE3s01 158 JP SETSEC ; SET SECTOR NUMBER - 0024 C3rECs01 159 JP SETDMA ; SET DMA ADDRESS - 0027 C3rF2s01 160 JP READ ; READ DISK - 002A C3rD7s03 161 JP WRITE ; WRITE DISK - 002D C3rBEs01 162 JP LISTST ; RETURN LIST STATUS (NULL ROUTINE) - 0030 C3rE9s01 163 JP SECTRN ; SECTOR TRANSLATE - 164 - 165 ;__________________________________________________________________________________________________ - 166 ; - 167 ; FIXED DATA TABLES FOR ALL DRIVES - 168 ; 0= FLOPPY DISK OR RAM DISK, 1=RAM DISK, 2=IDE, 3=ATAPI OR RAM DISK, 4=HDPART4 - 169 ; 5= 1MB ROM DISK,6=32K ROM DISK - 170 ; - 171 ; NOTE: The RAM disk area is used as a substitute if the Floppy and/or ZIP drives are not enabled - 172 ; in the sustem. This RAM disk is the same "disk" as drive B. - 173 ; - 174 ;__________________________________________________________________________________________________ - 175 - 176 ; DISK PARAMETER HEADER FOR DISK 00 - 0033 177 DPBASE: - 0033 00 00 00 00 178 .DW 0000,0000 - 0037 00 00 00 00 179 .DW 0000,0000 - 003Br1Ds0BrB2s00 180 .DW DIRBF,DPBLK1 - 003Fr4Es0FrDEs0B 181 .DW CHK01,ALL01 - 182 - 183 ; DISK PARAMETER HEADER FOR DISK 01 - 0001 184 .IF CONDUSEFLOPPY - 0001 185 .IF COND144FLOPPY - 0043 00 00 00 00 186 .DW 0000,0000 - 0047 00 00 00 00 187 .DW 0000,0000 - 004Br1Ds0Br0Cs01 188 .DW DIRBF,DPBLK7 ; FOR 1.44M FLOPPIES - 004FrCEs0FrC2s0E 189 .DW CHK07,ALL07 - 190 .ELSE - 191 .DW 0000,0000 - 192 .DW 0000,0000 - 193 .DW DIRBF,DPBLK0 - 194 .DW CHK00,ALL00 - 195 .ENDIF - 196 .ELSE - 197 .DW 0000,0000 - 198 .DW 0000,0000 - 199 .DW DIRBF,DPBLK1 - 200 .DW CHK01,ALL01 - 201 .ENDIF - 202 ; DISK PARAMETER HEADER FOR DISK 02 - 0053 00 00 00 00 203 .DW 0000,0000 - 0057 00 00 00 00 204 .DW 0000,0000 - 005Br1Ds0BrC1s00 205 .DW DIRBF,DPBLK2 - 005Fr4Es0FrFFs0B 206 .DW CHK02,ALL02 - 207 - 0000 208 .IF CONDUSEATAPI - 209 ; DISK PARAMETER HEADER FOR DISK 03 - 210 .DW 0000,0000 - 211 .DW 0000,0000 - 212 .DW DIRBF,DPBLK3 - 213 .DW CHK03,ALL03 - 214 .ELSE - 0063 00 00 00 00 215 .DW 0000,0000 - 0067 00 00 00 00 216 .DW 0000,0000 - 006Br1Ds0BrB2s00 217 .DW DIRBF,DPBLK1 - 006Fr4Es0FrDEs0B 218 .DW CHK01,ALL01 - 219 .ENDIF - 220 - 221 ; DISK PARAMETER HEADER FOR DISK 04 - 0073 00 00 00 00 222 .DW 0000,0000 - 0077 00 00 00 00 223 .DW 0000,0000 - 007Br1Ds0BrDFs00 224 .DW DIRBF,DPBLK4 - 007FrCEs0FrFFs0D 225 .DW CHK04,ALL04 - 226 - 227 ; DISK PARAMETER HEADER FOR DISK 05 - 0083 00 00 00 00 228 .DW 0000,0000 - 0087 00 00 00 00 229 .DW 0000,0000 - 008Br1Ds0BrEEs00 230 .DW DIRBF,DPBLK5 - 008FrCEs0Fr40s0E 231 .DW CHK05,ALL05 - 232 - 233 ; DISK PARAMETER HEADER FOR DISK 06 - 0093 00 00 00 00 234 .DW 0000,0000 - 0097 00 00 00 00 235 .DW 0000,0000 - 009Br1Ds0BrFDs00 236 .DW DIRBF,DPBLK6 - 009FrCEs0Fr81s0E 237 .DW CHK06,ALL06 - 238 ; - 239 - 00A3 240 DPBLK0: ; DISK PARAMETER BLOCK (FLOPPY DISK 720KB) - 00A3 24 00 241 SPT_0: .DW 36 ; 36 SECTORS OF 128 BYTES PER 4.5K TRACK - 00A5 04 242 BSH_0: .DB 4 ; BLOCK SHIFT FACTOR (SIZE OF ALLOCATION BLOCK) - 00A6 0F 243 BLM_0: .DB 15 ; PART OF THE ALLOCATION BLOCK SIZE MATH - 00A7 00 244 EXM_0: .DB 0 ; DEFINES SIZE OF EXTENT (DIRECTORY INFO) - 00A8 5E 01 245 DSM_0: .DW 350 ; BLOCKSIZE [2048] * NUMBER OF BLOCKS + 1 = DRIVE SIZE - 00AA 7F 00 246 DRM_0: .DW 127 ; NUMBER OF DIRECTORY ENTRIES - 00AC C0 247 AL0_0: .DB 0b11000000 ; BIT MAP OF SPACE ALLOCATED TO DIRECTORY - 00AD 00 248 AL1_0: .DB 0b00000000 ; DIRECTORY CAN HAVE UP TO 16 BLOCKS ALLOCATED - 00AE 20 00 249 CKS_0: .DW 32 ; SIZE OF DIRECTORY CHECK [0 IF NON REMOVEABLE] - 00B0 04 00 250 OFF_0: .DW 4 ; FIRST 4 TRACKS TRACKS RESERVED (18K FOR SYSTEM) - 251 ; - 00B2 252 DPBLK1: ; DISK PARAMETER BLOCK (RAMDISK 512K, 448K USABLE) - 00B2 00 01 253 SPT_1: .DW 256 ; 256 SECTORS OF 128 BYTES PER 32K TRACK - 00B4 04 254 BSH_1: .DB 4 ; BLOCK SHIFT FACTOR (SIZE OF ALLOCATION BLOCK) - 00B5 0F 255 BLM_1: .DB 15 ; PART OF THE ALLOCATION BLOCK SIZE MATH - 00B6 01 256 EXM_1: .DB 1 ; DEFINES SIZE OF EXTENT (DIRECTORY INFO) - 00B7 E1 00 257 DSM_1: .DW 225 ; BLOCKSIZE [2048] * NUMBER OF BLOCKS + 1 = DRIVE SIZE - 00B9 FF 00 258 DRM_1: .DW 255 ; NUMBER OF DIRECTORY ENTRIES - 00BB F0 259 AL0_1: .DB 0b11110000 ; BIT MAP OF SPACE ALLOCATED TO DIRECTORY - 00BC 00 260 AL1_1: .DB 0b00000000 ; DIRECTORY CAN HAVE UP TO 16 BLOCKS ALLOCATED - 00BD 00 00 261 CKS_1: .DW 0 ; SIZE OF DIRECTORY CHECK [0 IF NON REMOVEABLE] - 00BF 01 00 262 OFF_1: .DW 1 ; 1 TRACK RESERVED [FIRST 32K OF RAM] - 263 ; - 00C1 264 DPBLK2: ; DISK PARAMETER BLOCK (IDE HARD DISK 8MB) - 00C1 00 01 265 SPT_2: .DW 256 ; 256 SECTORS OF 128 BYTES PER 32K TRACK - 00C3 05 266 BSH_2: .DB 5 ; BLOCK SHIFT FACTOR (SIZE OF ALLOCATION BLOCK) - 00C4 1F 267 BLM_2: .DB 31 ; PART OF THE ALLOCATION BLOCK SIZE MATH - 00C5 01 268 EXM_2: .DB 1 ; DEFINES SIZE OF EXTENT (DIRECTORY INFO) - 00C6 E1 07 269 DSM_2: .DW 2017 ; BLOCKSIZE [4096] * NUMBER OF BLOCKS + 1 = DRIVE SIZE - 00C8 FF 01 270 DRM_2: .DW 511 ; NUMBER OF DIRECTORY ENTRIES - 00CA F0 271 AL0_2: .DB 0b11110000 ; BIT MAP OF SPACE ALLOCATED TO DIRECTORY - 00CB 00 272 AL1_2: .DB 0b00000000 ; DIRECTORY CAN HAVE UP TO 16 BLOCKS ALLOCATED - 00CC 00 00 273 CKS_2: .DW 0 ; SIZE OF DIRECTORY CHECK [0 IF NON REMOVEABLE] - 00CE F1 03 274 OFF_2: .DW 0x03F1 ; TRACKS (32K) RESERVED FOR SYSTEM AND OTHER PARTITIONS - 275 ; - 00D0 276 DPBLK3: ; DISK PARAMETER BLOCK (ATAPI DRIVE 8MB) - 00D0 00 01 277 SPT_3: .DW 256 ; 256 SECTORS OF 128 BYTES PER 32K TRACK - 00D2 05 278 BSH_3: .DB 5 ; BLOCK SHIFT FACTOR (SIZE OF ALLOCATION BLOCK) - 00D3 1F 279 BLM_3: .DB 31 ; PART OF THE ALLOCATION BLOCK SIZE MATH - 00D4 01 280 EXM_3: .DB 1 ; DEFINES SIZE OF EXTENT (DIRECTORY INFO) - 00D5 E1 07 281 DSM_3: .DW 2017 ; BLOCKSIZE [4096] * NUMBER OF BLOCKS + 1 = DRIVE SIZE - 00D7 FF 01 282 DRM_3: .DW 511 ; NUMBER OF DIRECTORY ENTRIES - 00D9 F0 283 AL0_3: .DB 0b11110000 ; BIT MAP OF SPACE ALLOCATED TO DIRECTORY - 00DA 00 284 AL1_3: .DB 0b00000000 ; DIRECTORY CAN HAVE UP TO 16 BLOCKS ALLOCATED - 00DB 00 00 285 CKS_3: .DW 0 ; SIZE OF DIRECTORY CHECK [0 IF NON REMOVEABLE] - 00DD 01 00 286 OFF_3: .DW 1 ; 1 TRACK (32K) RESERVED FOR SYSTEM - 287 ; - 00DF 288 DPBLK4: ; DISK PARAMETER BLOCK (IDE HARD DISK 1024K) - 00DF 00 01 289 SPT_4: .DW 256 ; 256 SECTORS OF 128 BYTES PER 32K TRACK - 00E1 04 290 BSH_4: .DB 4 ; BLOCK SHIFT FACTOR (SIZE OF ALLOCATION BLOCK) - 00E2 0F 291 BLM_4: .DB 15 ; PART OF THE ALLOCATION BLOCK SIZE MATH - 00E3 01 292 EXM_4: .DB 1 ; DEFINES SIZE OF EXTENT (DIRECTORY INFO) - 00E4 F1 01 293 DSM_4: .DW 497 ; BLOCKSIZE [2048] * NUMBER OF BLOCKS + 1 = DRIVE SIZE - 00E6 FF 00 294 DRM_4: .DW 255 ; NUMBER OF DIRECTORY ENTRIES - 00E8 F0 295 AL0_4: .DB 0b11110000 ; BIT MAP OF SPACE ALLOCATED TO DIRECTORY - 00E9 00 296 AL1_4: .DB 0b00000000 ; DIRECTORY CAN HAVE UP TO 16 BLOCKS ALLOCATED - 00EA 00 00 297 CKS_4: .DW 0 ; SIZE OF DIRECTORY CHECK [0 IF NON REMOVEABLE] - 00EC 01 00 298 OFF_4: .DW 1 ; 1 TRACK RESERVED [FIRST 32K OF PARTITION] - 299 ; - 00EE 300 DPBLK5: ; DISK PARAMETER BLOCK (ROMDISK 1MB) - 00EE 00 01 301 SPT_5: .DW 256 ; 256 SECTORS OF 128 BYTES PER 32K TRACK - 00F0 04 302 BSH_5: .DB 4 ; BLOCK SHIFT FACTOR (SIZE OF ALLOCATION BLOCK) - 00F1 0F 303 BLM_5: .DB 15 ; PART OF THE ALLOCATION BLOCK SIZE MATH - 00F2 00 304 EXM_5: .DB 0 ; DEFINES SIZE OF EXTENT (DIRECTORY INFO) - 00F3 FF 01 305 DSM_5: .DW 511 ; BLOCKSIZE [2048] * NUMBER OF BLOCKS +1 =DRIVE SIZE - 00F5 FF 00 306 DRM_5: .DW 255 ; NUMBER OF DIRECTORY ENTRIES - 00F7 F0 307 AL0_5: .DB 0b11110000 ; BIT MAP OF SPACE ALLOCATED TO DIRECTORY - 00F8 00 308 AL1_5: .DB 0b00000000 ; DIRECTORY CAN HAVE UP TO 16 BLOCKS ALLOCATED - 00F9 00 00 309 CKS_5: .DW 0 ; SIZE OF DIRECTORY CHECK [0 IF NON REMOVEABLE] - 00FB 01 00 310 OFF_5: .DW 1 ; 1 TRACK RESERVED [FIRST 32K OF ROM] - 311 ; - 00FD 312 DPBLK6: ; DISK PARAMETER BLOCK (ROMDISK 32KB) - 00FD 10 00 313 SPT_6: .DW 16 ; 16 SECTORS OF 128 BYTES PER 2K TRACK - 00FF 03 314 BSH_6: .DB 3 ; BLOCK SHIFT FACTOR (SIZE OF ALLOCATION BLOCK) - 0100 07 315 BLM_6: .DB 7 ; PART OF THE ALLOCATION BLOCK SIZE MATH - 0101 01 316 EXM_6: .DB 1 ; DEFINES SIZE OF EXTENT (DIRECTORY INFO) - 0102 1F 00 317 DSM_6: .DW 31 ; BLOCKSIZE [1024] * NUMBER OF BLOCKS + 1 = DRIVE SIZE - 0104 1F 00 318 DRM_6: .DW 31 ; NUMBER OF DIRECTORY ENTRIES - 0106 80 319 AL0_6: .DB 0b10000000 ; BIT MAP OF SPACE ALLOCATED TO DIRECTORY - 0107 00 320 AL1_6: .DB 0b00000000 ; DIRECTORY CAN HAVE UP TO 16 BLOCKS ALLOCATED - 0108 00 00 321 CKS_6: .DW 0 ; SIZE OF DIRECTORY CHECK [0 IF NON REMOVEABLE] - 010A 0A 00 322 OFF_6: .DW 10 ; FIRST 10 TRACKS TRACKS RESERVED (20K FOR SYSTEM) - 323 ; SYSTEM IS ROM LOADER, CCP, BDOS, CBIOS, AND MONITOR - 010C 324 DPBLK7: ; DISK PARAMETER BLOCK FLOPPY 1.44M - 010C 48 00 325 SPT_7: .DW 72 ; 16 SECTORS OF 128 BYTES PER 2K TRACK - 010E 04 326 BSH_7: .DB 4 ; BLOCK SHIFT FACTOR (SIZE OF ALLOCATION BLOCK) - 010F 0F 327 BLM_7: .DB 15 ; PART OF THE ALLOCATION BLOCK SIZE MATH - 0110 00 328 EXM_7: .DB 0 ; DEFINES SIZE OF EXTENT (DIRECTORY INFO) - 0111 C6 02 329 DSM_7: .DW 710 ; BLOCKSIZE [1024] * NUMBER OF BLOCKS + 1 = DRIVE SIZE - 0113 FF 00 330 DRM_7: .DW 255 ; NUMBER OF DIRECTORY ENTRIES - 0115 F0 331 AL0_7: .DB 0b11110000 ; BIT MAP OF SPACE ALLOCATED TO DIRECTORY - 0116 00 332 AL1_7: .DB 0b00000000 ; DIRECTORY CAN HAVE UP TO 16 BLOCKS ALLOCATED - 333 - 0117 20 00 334 CKS_7: .DW 32 ; SIZE OF DIRECTORY CHECK [0 IF NON REMOVEABLE] - 0119 02 00 335 OFF_7: .DW 2 ; FIRST 10 TRACKS TRACKS RESERVED (20K FOR SYSTEM) - 336 ; SYSTEM IS ROM LOADER, CCP, BDOS, CBIOS, AND MONITOR - 337 ; - 338 ; IMPORTANT NOTE: TRACKS 00h - 0AH OF 2K BYTES - 339 ; EACH ARE MARKED WITH THE OFF_6 SET TO 5 AS - 340 ; SYSTEM TRACKS USABLE ROM DRIVE SPACE - 341 ; STARTING AFTER THE TENTH TRACK (IE, TRACK 0AH) - 342 ; MOST LIKELY FIX TO THIS IS PLACING A DUMMY - 343 ; FIRST 20K ROM CONTAINS THE ROM LOADER, MONITOR, - 344 ; CCP, BDOS, BIOS, ETC (10 TRACKS * 2K EACH) - 345 ;__________________________________________________________________________________________________ - 346 ; - 347 ; END OF FIXED CP/M TABLES - 348 ; - 349 ; INDIVIDUAL SUBROUTINES TO PERFORM EACH FUNCTION - 350 ;__________________________________________________________________________________________________ - 351 - 352 - 353 ;___BOOT___________________________________________________________________________________________ - 011B 354 BOOT: ; SIMPLEST CASE IS TO JUST PERFORM PARAMETER INITIALIZATION - 355 ; - 011B 3E 80 356 LD A,#0x80 ; LOAD VALUE TO SWITCH OUT ROM - 011D D3 7C 357 OUT (MPCL_ROM),A ; SWITCH OUT ROM, BRING IN LOWER 32K RAM PAGE - 358 ; - 359 ; - 011F 3E 81 360 LD A,#0b10000001 ; SWITCH IN FIRST 32K LOWER PAGE (FIRST TRACK) - 0121 D3 78 361 OUT (MPCL_RAM),A ; - 362 ; FORMATTING THE RAM IS SIMPLE AS CLEARING THE DIRECTORY AREA - 363 ; TO A VALUE OF E5H (THE FIRST 8K OF TRACK 1 OR THE RAMDISK) - 0123 21 00 00 364 LD HL,#0000 ; STARTING MEMORY ADDRESS OF TRACK 1, SECTOR 0 IN HL - 0126 01 FF 1F 365 LD BC,#0x1FFF ; 8K OF DIRECTORY SECTORS RESERVED (LENGTH IN BC) - 0129 3E E5 366 LD A,#0x0E5 ; INITIALIZING VALUE IN A - 012B 5D 367 LD E,L ; - 012C 54 368 LD D,H ; - 012D 13 369 INC DE ; - 012E 77 370 LD (HL),A ; - 012F ED B0 371 LDIR ; - 372 ; - 0131 3E 80 373 LD A,#0x80 ; LOAD VALUE TO SWITCH OUT ROM - 0133 D3 7C 374 OUT (MPCL_ROM),A ; SWITCH OUT ROM, BRING IN LOWER 32K RAM PAGE - 375 ; - 0135 3E 00 376 LD A,#0 ; ENSURE LOWEST RAM PAGE SELECTED - 0137 D3 78 377 OUT (MPCL_RAM),A ; BRING IN LOWEST 32K RAM PAGE - 378 ; - 0139 AF 379 XOR A ; ZERO IN THE ACCUM - 013A 32 03 00 380 LD (IOBYTE),A ; CLEAR THE IOBYTE - 013D 32 04 00 381 LD (CDISK),A ; SELECT DISK 0 - 382 ; - 0140 CDrC3s05 383 CALL IDE_SOFT_RESET ; RESET THE IDE HARD DISK - 384 ; - 385 ; - 0143 C3r67s01 386 JP GOCPM ; INITIALIZE AND GO TO CP/M - 387 ; - 388 ; - 389 ;___WBOOT__________________________________________________________________________________________ - 0146 390 WBOOT: ; SIMPLEST CASE IS TO READ THE DISK UNTIL ALL SECTORS LOADED - 391 ; WITH A ROMDISK WE SELECT THE ROM AND THE CORRECT PAGE [0] - 392 ; THEN COPY THE CP/M IMAGE (CCP, BDOS, BIOS, MONITOR) TO HIGH RAM - 393 ; LOAD ADDRESS - 394 ; FOR Z80 IT LOOKS LIKE THIS . USING 8080 NEMONICS - 395 ; - 0146 F3 396 DI ; DISABLE INTERRUPT - 0147 31 80 00 397 LD SP,#0x80 ; USE SPACE BELOW BUFFER FOR STACK - 014A ED 56 398 IM 1 ; SET INTERRUPT MODE 1 - 399 ; - 014C AF 400 XOR A ; CHEAP ZERO IN ACC - 014D D3 7C 401 OUT (MPCL_ROM),A ; SEND 0 TO ROM MAP PORT (SWITCH IN LOWER 32K ROM PAGE) - 402 ; - 014F AF 403 XOR A ; CHEAP ZERO IN ACC - 0150 D3 78 404 OUT (MPCL_RAM),A ; SEND 0 TO RAM MAP PORT (SELECT LOWEST RAM PAGE) - 405 ; - 0152 21 00 0A 406 LD HL,#ROMSTART_CPM ; WHERE IN ROM CP/M IS STORED (FIRST BYTE) - 0155 11 00 D0 407 LD DE,#RAMTARG_CPM ; WHERE IN RAM TO MOVE MONITOR TO (FIRST BYTE) - 0158 01 00 08 408 LD BC,#CCPSIZ_CPM ; NUMBER OF BYTES TO MOVE FROM ROM TO RAM - 015B ED B0 409 LDIR ; - 410 ; - 411 ; - 412 ;;;;; EI ; ENABLE INTERRUPTS - 015D 3E 80 413 LD A,#0x80 ; LOAD VALUE TO SWITCH OUT ROM - 015F D3 7C 414 OUT (MPCL_ROM),A ; SWITCH OUT ROM, BRING IN LOWER 32K RAM PAGE - 415 ; - 0161 AF 416 XOR A ; CHEAP ZERO IN ACC - 0162 D3 78 417 OUT (MPCL_RAM),A ; SEND 0 TO RAM MAP PORT (SELECT LOWEST RAM PAGE) - 418 ; - 0164 CDrC3s05 419 CALL IDE_SOFT_RESET ; RESET THE IDE HARD DISK - 420 ; - 0001 421 .IF CONDSUPERSUB ; - 422 ; DO NOTHING FOR ORIGINAL CODE - 423 .ELSE ; - 424 ; CLEAR THE AUTOSUB BUFFER, DO ON A WARM BOOT - 425 XOR A ; - 426 LD (INBUFF+1),A ; SECOND BYTE IS ACTUAL LENGTH - 427 .ENDIF ; - 428 ; FALL THROUGH TO GOCPM ROUTINE - 429 ; - 430 ; END OF LOAD OPERATION, SET PARAMETERS AND GO TO CP/M - 431 ; - 432 ;___GOCPM__________________________________________________________________________________________ - 0167 433 GOCPM: - 434 ; CPU RESET HANDLER - 0167 3E C3 435 LD A,#0x0C3 ; C3 IS A JMP INSTRUCTION - 0169 32 00 00 436 LD (0),A ; FOR JMP TO WBOOT - 016C 21r03s00 437 LD HL,#WBOOTE ; WBOOT ENTRY POINT - 016F 22 01 00 438 LD (1),HL ; SET ADDRESS FIELD FOR JMP AT 0 - 439 ; - 440 ; CPU INTERRUPT HANDLER - 0172 3E C3 441 LD A,#0x0C3 ; C3 IS A JMP INSTRUCTION - 0174 32 38 00 442 LD (0x0038),A ; FOR JMP TO WBOOT - 0177 21r03s00 443 LD HL,#WBOOTE ; WBOOT ENTRY POINT - 017A 22 01 00 444 LD (1),HL ; SET ADDRESS FIELD FOR JMP AT 0 - 445 ; - 017D 32 05 00 446 LD (5),A ; FOR JMP TO BDOS - 0180 21 06 D8 447 LD HL,#BDOS ; BDOS ENTRY POINT - 0183 22 06 00 448 LD (6),HL ; ADDRESS FIELD OF JUMP AT 5 TO BDOS - 449 ; - 0186 01 80 00 450 LD BC,#0x80 ; DEFAULT DMA ADDRESS IS 80H - 0189 CDrECs01 451 CALL SETDMA ; - 452 ; - 0001 453 .IF CONDUSEFLOPPY ; - 018C CDrBFs07 454 CALL SETUPDRIVE ; SETUP FLOPPY PARAMETERS - 455 .ENDIF ; - 456 ; - 0000 457 .IF CONDUSEVDU ; - 458 DI ; DISABLE INTERRUPTS - 459 LD A,#0x1F ; SET HIGH ROM PAGE - 460 OUT (MPCL_ROM),A ; SEND TO ROM PORT MAPPER - 461 LD HL,#0 ; - 462 ADD HL,SP ; GET STACK POINTER INTO HL - 463 LD (PARKSTACK),HL ; SAVE STACK POINTER - 464 LD SP,#FLOPPYSTACK ; - 465 CALL VDU_INIT ; - 466 LD SP,(PARKSTACK) ; RESTORE STACK - 467 LD A,#0x80 ; LOAD VALUE TO SWITCH OUT ROM - 468 OUT (MPCL_ROM),A ; - 469 LD A,#0 ; CHOOSE HIGHEST RAM PAGE - 470 OUT (MPCL_RAM),A ; SEND 19H TO RAM MAP PORT (SELECT HIGHEST RAM PAGE) - 471 ;;;;; EI ; ENABLE INTERRUPTS - 472 .ENDIF ; - 018F 21rADs0A 473 LD HL,#TXT_STARTUP_MSG ; PRINT STARTUP MESSAGE - 0192 CDrBCs04 474 CALL PRTMSG ; - 475 ; - 0195 3A 04 00 476 LD A,(CDISK) ; GET CURRENT DISK NUMBER - 0198 4F 477 LD C,A ; SEND TO THE CCP - 0199 C3 00 D0 478 JP CCP ; GO TO CP/M FOR FURTHER PROCESSING - 479 ; - 480 ;__________________________________________________________________________________________________ - 481 ; - 482 ; ** CONSOLE & PRINTER I/O -- VDU CARD DRIVER INTERFACE - 483 ; - 484 ;__________________________________________________________________________________________________ - 0000 485 .IF CONDUSEVDU - 486 CONST: - 487 PUSH HL ; STORE HL - 488 DI ; DISABLE INTERRUPTS - 489 LD A,#1FH ; SET HIGH ROM PAGE - 490 OUT (MPCL_ROM),A ; SEND TO ROM PORT MAPPER - 491 LD HL,#0 ; - 492 ADD HL,SP ; GET STACK POINTER INTO HL - 493 LD (PARKSTACK),HL ; SAVE STACK POINTER - 494 LD SP,#FLOPPYSTACK ; - 495 CALL IS_KBHIT ; CHECK FOR KB HIT - 496 LD C,A ; STORE RESULT - 497 LD SP,(PARKSTACK) ; RESTORE STACK - 498 LD A,#0x80 ; LOAD VALUE TO SWITCH OUT ROM - 499 OUT (MPCL_ROM),A ; - 500 LD A,#0 ; CHOOSE HIGHEST RAM PAGE - 501 OUT (MPCL_RAM),A ; SEND 19H TO RAM MAP PORT (SELECT HIGHEST RAM PAGE) - 502 LD A,C ; RESTORE RESULT - 503 ;;;;; EI ; ENABLE INTERRUPTS - 504 POP HL ; RESTORE HL - 505 RET - 506 - 507 CONIN: - 508 PUSH HL ; STORE HL - 509 DI ; DISABLE INTERRUPTS - 510 LD A,#0x1F ; SET HIGH ROM PAGE - 511 OUT (MPCL_ROM),A ; SEND TO ROM PORT MAPPER - 512 LD HL,#0 ; - 513 ADD HL,SP ; GET STACK POINTER INTO HL - 514 LD (PARKSTACK),HL ; SAVE STACK POINTER - 515 LD SP,#FLOPPYSTACK ; - 516 CALL GET_KEY ; GET KEY FROM KEYBOARD - 517 LD C,A ; STORE RESULT - 518 LD SP,(PARKSTACK) ; RESTORE STACK - 519 LD A,#0x80 ; LOAD VALUE TO SWITCH OUT ROM - 520 OUT (MPCL_ROM),A ; - 521 LD A,#0x00 ; CHOOSE HIGHEST RAM PAGE - 522 OUT (MPCL_RAM),A ; SEND 19H TO RAM MAP PORT (SELECT HIGHEST RAM PAGE) - 523 LD A,C ; RESTORE RESULT - 524 ;;;;; EI ; ENABLE INTERRUPTS - 525 POP HL ; RESTORE HL - 526 RET - 527 - 528 CONOUT: - 529 PUSH HL ; STORE HL - 530 DI ; DISABLE INTERRUPTS - 531 LD A,#0x1F ; SET HIGH ROM PAGE - 532 OUT (MPCL_ROM),A ; SEND TO ROM PORT MAPPER - 533 LD HL,#0 ; - 534 ADD HL,SP ; GET STACK POINTER INTO HL - 535 LD (PARKSTACK),HL ; SAVE STACK POINTER - 536 LD SP,#FLOPPYSTACK ; - 537 LD A,C ; RESTORE CHARACTER - 538 CALL CHARIN ; DISPLAY CHARACTER - 539 LD SP,(PARKSTACK) ; RESTORE STACK - 540 LD A,#0x80 ; LOAD VALUE TO SWITCH OUT ROM - 541 OUT (MPCL_ROM),A ; - 542 LD A,#0x00 ; CHOOSE HIGHEST RAM PAGE - 543 OUT (MPCL_RAM),A ; SEND 19H TO RAM MAP PORT (SELECT HIGHEST RAM PAGE) - 544 ;;;;; EI ; ENABLE INTERRUPTS - 545 POP HL ; RESTORE HL - 546 RET - 547 LIST: - 548 PUSH HL ; STORE HL - 549 DI ; DISABLE INTERRUPTS - 550 LD A,#0x1F ; SET HIGH ROM PAGE - 551 OUT (MPCL_ROM),A ; SEND TO ROM PORT MAPPER - 552 LD HL,#0 ; - 553 ADD HL,SP ; GET STACK POINTER INTO HL - 554 LD (PARKSTACK),HL ; SAVE STACK POINTER - 555 LD SP,#FLOPPYSTACK ; - 556 LD A,C ; RESTORE CHARACTER - 557 CALL PR_OUTCHAR ; - 558 LD SP,(PARKSTACK) ; RESTORE STACK - 559 LD A,#0x80 ; LOAD VALUE TO SWITCH OUT ROM - 560 OUT (MPCL_ROM),A ; - 561 LD A,#0x00 ; CHOOSE HIGHEST RAM PAGE - 562 OUT (MPCL_RAM),A ; SEND 19H TO RAM MAP PORT (SELECT HIGHEST RAM PAGE) - 563 ;;;;; EI ; ENABLE INTERRUPTS - 564 POP HL ; RESTORE HL - 565 RET - 566 - 567 ;__________________________________________________________________________________________________ - 568 ; - 569 ; ** CONSOLE I/O -- ON-BOARD 16550 SERIAL INTERFACE - 570 ; - 571 ;__________________________________________________________________________________________________ - 572 .ELSE - 019C 573 CONST: ; CONSOLE STATUS, RETURN 0FFH IF CHARACTER READY, 00H IF NOT - 019C DB 6D 574 IN A,(UART + 5) ; READ LINE STATUS REGISTER (UART5 = 068h + $05) - 019E E6 01 575 AND #0x01 ; TEST IF DATA IN RECEIVE BUFFER - 576 ; IS THERE A CHAR READY? 0=NO, 1=YES - 01A0 CArA5s01 577 JP Z,NOT_READY ; - 01A3 3E FF 578 LD A,#0x0FF ; YES, PUT 0FFh IN A AND RETURN - 01A5 579 NOT_READY: ; - 580 ; NO, LEAVE 000h IN A AND RETURN - 01A5 C9 581 RET ; - 01A6 582 CONIN: ; CONSOLE CHARACTER INTO REGISTER A - 583 ; - 01A6 CDr9Cs01 584 CALL CONST ; IS A CHAR READY TO BE READ FROM UART? - 01A9 FE 00 585 CP #0 ; - 01AB CArA6s01 586 JP Z,CONIN ; NO? TRY AGAIN - 01AE DB 68 587 IN A,(UART) ; YES? READ THE CHAR FROM THE UART (UART0 = 068h + $00) - 588 ; REGISTER AND PASS BACK TO USER - 01B0 C9 589 RET ; - 590 ; - 01B1 591 CONOUT: ; CONSOLE CHARACTER OUTPUT FROM REGISTER C - 01B1 DB 6D 592 IN A,(UART + 5) ; READ LINE STATUS REGISTER - 01B3 E6 20 593 AND #0x20 ; TEST IF UART IS READY TO SEND - 01B5 CArB1s01 594 JP Z,CONOUT ; IF NOT REPEAT - 595 ; - 01B8 79 596 LD A,C ; GET TO ACCUMULATOR - 01B9 D3 68 597 OUT (UART),A ; THEN WRITE THE CHAR TO UART (UART0 = 068h + $00) - 01BB C9 598 RET ; - 599 ; - 01BC 600 LIST: ;LIST CHARACTER FROM REGISTER C - 01BC 79 601 LD A,C ;CHARACTER TO REGISTER A - 01BD C9 602 RET ;NULL SUBROUTINE - 603 .ENDIF - 604 ; - 01BE 605 LISTST: ;RETURN LIST STATUS (0 IF NOT READY, 1 IF READY) - 01BE AF 606 XOR A ;0 IS ALWAYS OK TO RETURN - 01BF C9 607 RET ; - 608 ; - 609 ; - 610 ;__________________________________________________________________________________________________ - 611 ; - 612 ; ** PUNCH & READER I/O -- STUB - 613 ; - 614 ;__________________________________________________________________________________________________ - 01C0 615 PUNCH: ;PUNCH CHARACTER FROM REGISTER C - 01C0 79 616 LD A,C ;CHARACTER TO REGISTER A - 01C1 C9 617 RET ;NULL SUBROUTINE - 618 ; - 01C2 619 READER: ;READ CHARACTER INTO REGISTER A FROM READER DEVICE - 01C2 79 620 LD A,C ;CHARACTER TO REGISTER A - 01C3 C9 621 RET - 622 - 623 - 624 ;__________________________________________________________________________________________________ - 625 ; - 626 ; ** DISK STORAGE I/O - 627 ; - 628 ;__________________________________________________________________________________________________ - 629 ; - 630 ; SELECT DISK GIVEN BY REGISTER C - 631 ;__________________________________________________________________________________________________ - 632 - 01C4 21 00 00 633 SELDSK: LD HL,#0x0000 ; ERROR RETURN CODE - 01C7 79 634 LD A,C ; - 0001 635 .IF CONDABONLY ; - 01C8 FE 07 636 CP #7 ; MUST BE BETWEEN 0 AND 6 - 637 .ELSE ; - 638 CP #2 ; IF NO IDE THEN ONLY DRIVE A AND B FOR THE MINI N8VEM SO 0 OR 1 ONLY - 639 .ENDIF ; - 01CA D0 640 RET NC ; RETURN IF OUT OF RANGE - 01CB 32r12s0B 641 LD (DISKNO),A ; - 642 ; DISK NUMBER IS IN THE PROPER RANGE - 643 ; COMPUTE PROPER DISK PARAMETER HEADER ADDRESS - 01CE 6F 644 LD L,A ; L=DISK NUMBER 0,1,2,3,4 - 01CF 26 00 645 LD H,#0 ; HIGH ORDER ZERO - 01D1 29 646 ADD HL,HL ; *2 - 01D2 29 647 ADD HL,HL ; *4 - 01D3 29 648 ADD HL,HL ; *8 - 01D4 29 649 ADD HL,HL ; *16 (SIZE OF EACH HEADER) - 01D5 11r33s00 650 LD DE,#DPBASE ; - 01D8 19 651 ADD HL,DE ; HL= DPBASE(DISKNO*16) - 01D9 C9 652 RET - 653 ;__________________________________________________________________________________________________ - 01DA 654 HOME: ; MOVE TO THE TRACK 00 POSITION OF CURRENT DRIVE - 655 ; TRANSLATE THIS CALL INTO A SETTRK CALL WITH PARAMETER 00 - 01DA 01 00 00 656 LD BC,#0 ; SELECT TRACK 0000 - 657 ;__________________________________________________________________________________________________ - 01DD 658 SETTRK: ; SET TRACK GIVEN BY REGISTER BC - 01DD 60 659 LD H,B ; - 01DE 69 660 LD L,C ; - 01DF 22r02s0B 661 LD (TRACK),HL ; - 01E2 C9 662 RET - 663 ;__________________________________________________________________________________________________ - 01E3 664 SETSEC: ; SET SECTOR GIVEN BY REGISTER BC - 01E3 60 665 LD H,B ; - 01E4 69 666 LD L,C ; - 01E5 22r0As0B 667 LD (SECTOR),HL ; - 01E8 C9 668 RET ; - 669 ;__________________________________________________________________________________________________ - 670 ; - 671 ; TRANSLATE THE SECTOR GIVEN BY BC USING THE - 672 ; TRANSLATE TABLE GIVEN BY DE - 673 ; ONLY USED FOR FLOPPIES! FOR ROMDISK/RAMDISK/IDE/ATAPI IT'S 1:1 - 674 ; DO THE NEXT ROUTINE IS A NULL (RETURNS THE SAME) - 675 ;__________________________________________________________________________________________________ - 01E9 676 SECTRN: - 01E9 60 677 LD H,B ; - 01EA 69 678 LD L,C ; - 01EB C9 679 RET ; - 680 ;__________________________________________________________________________________________________ - 01EC 681 SETDMA: ; SET DMA ADDRESS GIVEN BY REGISTERS B AND C - 01EC 69 682 LD L,C ; LOW ORDER ADDRESS - 01ED 60 683 LD H,B ; HIGH ORDER ADDRESS - 01EE 22r10s0B 684 LD (DMAAD),HL ; SAVE THE ADDRESS - 01F1 C9 685 RET - 686 ;________________________________________________________________________________________________________ - 687 ; DISK DRIVERS . - 688 ; - 689 ; DRIVER NEEDS TO DO SEVERAL THINGS FOR ROM AND RAM DISKS - 690 ; - INTERRUPTS ARE NOT ALLOWED DURING LOW RAM/ROM ACCESS (DISABLE!) - 691 ; -TRANSLATE TRACK AND SECTOR INTO A POINTER TO WHERE THE 128 BYTE - 692 ; SECTOR BEGINS IN THE RAM/ROM - 693 ; -TRANSLATE THE DRIVE INTO A RAM/ROM SELECT, COMBINE WITH TRACK ADDRESS - 694 ; AND SEND TO THE MAP PORT - 695 ; -COPY 128 BYTE FROM OR TO THE ROM/RAMDISK AND MEMORY POINTED TO BY THE DMA - 696 ; ADDRESS PREVIOUSLY STORED - 697 ; -RESTORE MAP PORT TO PRIOR CONDITION BEFOR READ/WRITE - 698 ; - 699 ; - FIRST TRICK IS THAT WE MADE SECTORS 256 AS 256*128=32768 SO WE COPY - 700 ; THE LOW SECTOR ADDRESS TO THE LOW BYTE OF THE HL REGISTER AND THEN - 701 ; MULTIPLY BY 128 THIS RESULTS IN THE STARTING ADDRESS IN THE RAM OR ROM - 702 ; (0000 -> 7F80H) 32K PAGE - 703 ; - 704 ; - TRICK TWO IS THE TRACK ADDRESS EQUALS THE 32K PAGE ADDRESS AND IS A - 705 ; DIRECT SELECT THAT CAN BE COPIED TO THE MAP PORT D0 THROUGH D5 D7 - 706 ; SELECTS THE DRIVE (ROM OR RAM) - 707 ; THAT MEANS THE LOW BYTE OF TRACK CONTAINS THE D0-D5 VALUE AND - 708 ; DISKNO HAS THE DRIVE SELECTED WE FIRST COPY DISKNO TO ACC - 709 ; AND RIGHTSHIFT IT TO PLACE THAT IN BIT 7, WE THEN ADD THE LOW BYTE OF - 710 ; TRACK TO ACC AND THEN SEND THAT TO THE MAP PORT - 711 ; - 712 ; NOTE 1: A WRITE TO ROM SHOULD BE FLAGGED AS AN ERROR - 713 ; NOTE 2: RAM MUST START AS A "FORMATTED DISK" IF BATTERY BACKED UP - 714 ; IT'S A DO ONCE AT COLD COLD START IF NOT BATTERY BACKED U - 715 ; IT WILL HAVE TO BE DONE EVERY TIME THE SYSTEM IS POWERED - 716 ; FORMATTING THE RAM IS SIMPLE AS CLEARING THE DIRECTORY AREA - 717 ; TO A VALUE OF E5H (THE FIRST 8K OF TRACK 1 OR THE RAMDISK) - 718 ; IT COULD BE DONE AS A SIMPLE UTILITY PROGRAM STORED IN ROMD - 719 ; OR ANYTIME COLBOOT IS CALLED(LESS DESIREABLE) - 720 ; - 721 ; -WE NOW CAN COPY TO OR FROM AS CORRECT FOR THE DEVICE 128 BYTES (SECTOR) - 722 ; TO OR FROM THE DMA ADDRESS ALMOST! SINCE ROM OR RAM IS BEING PAGED - 723 ; WE HAVE TO COPY ANYTHING DETINED FOR BELOW 8000H TO A TEMP BUFFER THEN - 724 ; HANDLE THE PAGING - 725 ; - 726 ; - 727 ; - LAST STEP IS TO RESTORE THE MAP PORT TO POINT TO THE RAM (TRACK 0) SO T - 728 ; MEMORY MAP IS ALL RAM AGAIN AND NOT POINTING INTO THE DATA AREAS OR THE - 729 ; SINCE THE RAM 0TH PAGE IS NOMINALLY THE LOW 32K OF RAM IN THE SYSTEM WE - 730 ; SEND A SIMPLE MVI A,80H ; OUT MPCL_ROM ; MVI A,00H ; OUT MPCL_RAM - 731 ; - 732 ; - THE READ OR WRITE OPERATION IS DONE - 733 ; - 734 ; READ DISK - 735 ; USES DE,DL, BC, ACC FLAGS - 736 ; Z80 COULD USE BLOCK MOVE [LDIR] BUT WRITTEN IN 8080 - 737 ;________________________________________________________________________________________________________ - 738 - 739 ;__READ__________________________________________________________________________________________________ - 740 ; - 741 ; PERFORM CP/M SECTOR READ - 742 ;________________________________________________________________________________________________________ - 01F2 743 READ: - 01F2 F3 744 DI ; DISABLE INTERRUPTS - 01F3 3Ar12s0B 745 LD A,(DISKNO) ; GET DRIVE - 01F6 FE 01 746 CP #0x01 ; "B" - 0001 747 .IF CONDUSEFLOPPY - 01F8 CArFEs02 748 JP Z,READ_FLPY_DSK ; READ FLOPPY - 749 .ELSE - 750 JP Z,READ_RAM_DISK ; READ FROM 448K RAM DISK - 751 .ENDIF - 01FB FE 00 752 CP #0 ; "B" - 01FD CAr5As02 753 JP Z,READ_RAM_DISK ; READ FROM 448K RAM DISK - 0200 FE 02 754 CP #2 ; "C" - 0202 CAr78s03 755 JP Z,READ_IDE ; READ FROM 8 MB IDE HARD DISK - 0205 FE 03 756 CP #3 ; "D" - 0000 757 .IF CONDUSEATAPI - 758 JP Z,READ_ATAPI ; READ FROM 8 MB ATAPI - 759 .ELSE - 0207 CAr5As02 760 JP Z,READ_RAM_DISK ; READ FROM 448K RAM DISK - 761 .ENDIF - 762 - 020A FE 04 763 CP #4 ; "E" - 020C CArD6s03 764 JP Z,READ_HDPART4 ; READ FROM 1 MB IDE HARD DISK, PARTITION 4 ** future use - 020F FE 05 765 CP #5 ; "F" - 0211 CAr5As02 766 JP Z,READ_RAM_DISK ; READ FROM 1M ROM DISK (UTILIZES SAME - 767 ; ROUTINES AS RAM_DISK - 768 ; "G" - 769 ; READ FROM 22K EEPROM DISK , SO FALL THROUGH - 770 - 771 ;___READ_EEPROM_DISK_____________________________________________________________________________________ - 772 ; - 773 ; READ EEPROM DISK - 774 ;________________________________________________________________________________________________________ - 0214 775 READ_EEPROM_DISK: - 776 ; - 777 ; IF ROM, MAP TRACK/SECTOR TO VIRTUAL TRACK/SECTOR - 778 ; HANDLE READING FROM ROM HERE - 779 ; - 780 ; PURPOSE OF THIS ROUTINE IS TO MAP 32K ROM PART - 781 ; TRACK/SECTOR MAP (2K TRACK SIZE MADE OF 16 128 - 782 ; BYTE SECTORS EACH) ONTO WHAT THE RAM/ROM SECTOR - 783 ; READ ROUTINES ARE EXPECTING (32K TRACK SIZE MADE - 784 ; OF 256 128 BYTE SECTORS EACH) THE ROUTINE - 785 ; CONVERTS 4 BIT TRACK # AND 4 BIT SECTOR # - 786 ; INTO A VIRTUAL 1 TRACK, 256 SECTOR ACCESS - 0214 2Ar02s0B 787 LD HL,(TRACK) ; TRACK # IS UPPER 4 BITS OF SECTOR ADDRESS - 0217 29 788 ADD HL,HL ; SHIFT BITS LEFT 1 (*2) - 0218 29 789 ADD HL,HL ; SHIFT BITS LEFT 1 (*4) - 0219 29 790 ADD HL,HL ; SHIFT BITS LEFT 1 (*8) - 021A 29 791 ADD HL,HL ; SHIFT BITS LEFT 1 (*16) - 021B 44 792 LD B,H ; PUT UPPER 4 BITS OF SECTOR ADDRESS IN BC - 021C 4D 793 LD C,L ; (B IS UPPER BYTE AND C IS LOWER BYTE) - 794 ; BC NOW CONTAINS THE UPDATED TRACK # - 021D 2Ar0As0B 795 LD HL,(SECTOR) ; SECTOR # IS LOWER 4 BITS OF SECTOR ADDRESS - 0220 09 796 ADD HL,BC ; VIRTUAL SECTOR = (UPDATED TRACK #) + SECTOR # - 0221 22r0Cs0B 797 LD (PSECTOR),HL ; STORE VIRTUAL SECTOR # - 798 ; NOW CONTINUE READING ROM WITH REGULAR RAM - 799 ; SETUP FOR READ OF RAM OR ROM DISK - 0224 2Ar0Cs0B 800 LD HL,(PSECTOR) ; - 0227 29 801 ADD HL,HL ; SHIFT BITS LEFT 1 (*2) - 0228 29 802 ADD HL,HL ; SHIFT BITS LEFT 1 (*4) - 0229 29 803 ADD HL,HL ; SHIFT BITS LEFT 1 (*8) - 022A 29 804 ADD HL,HL ; SHIFT BITS LEFT 1 (*16) - 022B 29 805 ADD HL,HL ; SHIFT BITS LEFT 1 (*32) - 022C 29 806 ADD HL,HL ; SHIFT BITS LEFT 1 (*64) - 022D 29 807 ADD HL,HL ; SHIFT BITS LEFT 1 (*128) - 022E 22r0Es0B 808 LD (SECST),HL ; SAVE SECTOR STARTING ADDRESS - 809 ; SET PAGER WITH DRIVE (0) AND TRACK (0) - 0231 3E 00 810 LD A,#0 ; SWITCH IN ROM PAGE - 0233 D3 7C 811 OUT (MPCL_ROM),A ; SEND TO PORT MAPPER - 0235 32r08s0B 812 LD (PAGER),A ; SAVE COPY (JUST BECAUSE) - 0238 21rE2s0F 813 LD HL,#SECTOR_BUFFER ; LOAD HL WITH TEMP BUF ADDRESS - 023B 5D 814 LD E,L ; - 023C 54 815 LD D,H ; GET IT INTO DE - 023D 2Ar0Es0B 816 LD HL,(SECST) ; GET ROM/RAM ADDRESS - 0240 CDr10s05 817 CALL COPY_CPM_SECTOR ; - 0243 CDr04s05 818 CALL RPAGE ; SET PAGE TO CP/M RAM - 0246 2Ar10s0B 819 LD HL,(DMAAD) ; LOAD HL WITH DMA ADDRESS - 0249 5D 820 LD E,L ; - 024A 54 821 LD D,H ; GET IT INTO DE - 024B 21rE2s0F 822 LD HL,#SECTOR_BUFFER ; GET ROM/RAM ADDRESS - 024E CDr10s05 823 CALL COPY_CPM_SECTOR ; - 0251 3Ar12s0B 824 LD A,(DISKNO) ; STORE CURRENT DRIVE IN BUFFER - 0254 32rDDs0F 825 LD (CUDISK),A ; - 0257 3E 00 826 LD A,#0 ; - 827 ;;;;; EI ; RE-ENABLE INTERRUPTS - 0259 C9 828 RET - 829 ;___READ_RAM_DISK_________________________________________________________________________________________ - 830 ; - 831 ; READ RAM DISK - 832 ;________________________________________________________________________________________________________ - 025A 833 READ_RAM_DISK: ; - 834 ; IF RAM, PROCEED WITH NORMAL TRACK/SECTOR READ - 025A CDrCBs04 835 CALL SECPAGE ; SETUP FOR READ OF RAM OR ROM DISK - 025D CDrD9s04 836 CALL PAGERB ; SET PAGER WITH DRIVE AND TRACK - 0260 21rE2s0F 837 LD HL,#SECTOR_BUFFER ; LOAD HL WITH TEMP BUF ADDRESS - 0263 5D 838 LD E,L ; - 0264 54 839 LD D,H ; GET IT INTO DE - 0265 2Ar0Es0B 840 LD HL,(SECST) ; GET ROM/RAM ADDRESS - 0268 CDr10s05 841 CALL COPY_CPM_SECTOR ; MOVE SECTOR TO SECTOR_BUFFER - 026B CDr04s05 842 CALL RPAGE ; SET PAGE TO CP/M RAM - 026E 2Ar10s0B 843 LD HL,(DMAAD) ; LOAD HL WITH DMA ADDRESS ; - 0271 5D 844 LD E,L ; - 0272 54 845 LD D,H ; GET IT INTO DE - 0273 21rE2s0F 846 LD HL,#SECTOR_BUFFER ; GET ROM/RAM ADDRESS - 0276 CDr10s05 847 CALL COPY_CPM_SECTOR ; MOVE SECTOR FROM SECTOR_BUFFER TO DMA AREA - 0279 3Ar12s0B 848 LD A,(DISKNO) ; STORE CURRENT DRIVE IN BUFFER - 027C 32rDDs0F 849 LD (CUDISK),A ; - 027F 3E 00 850 LD A,#0 ; - 851 ;;;;; EI ; RE-ENABLE INTERRUPTS - 0281 C9 852 RET - 853 - 854 ;___TRFLSEC______________________________________________________________________________________________ - 855 ; - 856 ; TRANSLATE LOGICAL FLOPPY DISK SECTOR TO PHYSICAL SECTOR - 857 ; IN: TRACK,SECTOR - 858 ; OUT: PTRACK,PSECTOR,SECTOR_INDEX - 859 ;________________________________________________________________________________________________________ - 0282 860 TRFLSEC: - 0282 3Ar02s0B 861 LD A,(TRACK) ; LOAD TRACK # (LOW BYTE) - 0285 E6 01 862 AND #1 ; FILTER OUT HEAD - 0287 32rEBs0A 863 LD (HEAD),A ; STORE HEAD - 028A 3Ar02s0B 864 LD A,(TRACK) ; SAVE TRACK IN A - 028D CB 3F 865 SRL A ; REMOVE HEAD BIT - 028F 32r04s0B 866 LD (PTRACK),A ; STORE IN TRACK - 0292 3Ar0As0B 867 LD A,(SECTOR) ; LOAD SECTOR # (LOW BYTE) - 0295 32r1Cs0B 868 LD (SECTOR_INDEX),A ; STORE SECTOR IN SECTOR INDEX - 0298 CB 3F 869 SRL A ; - 029A CB 3F 870 SRL A ; DIVIDE BY 4 (FOR BLOCKING) - 029C 32r0Cs0B 871 LD (PSECTOR),A ; STORE IN SECTOR - 029F 3Ar1Cs0B 872 LD A,(SECTOR_INDEX) ; FILTER OUT UNWANTED BITS - 02A2 E6 03 873 AND #3 ; - 02A4 32r1Cs0B 874 LD (SECTOR_INDEX),A ; - 02A7 C9 875 RET - 876 - 877 ;___DEBSEC_______________________________________________________________________________________________ - 878 ; - 879 ; DEBLOCK 512 BYTE SECTOR FOR CP/M - 880 ; - 881 ;________________________________________________________________________________________________________ - 02A8 882 DEBSEC: - 02A8 2Ar10s0B 883 LD HL,(DMAAD) ; LOAD HL WITH DMA ADDRESS - 02AB 54 884 LD D,H ; TRANSFER HL REGISTERS TO DE - 02AC 5D 885 LD E,L ; - 02AD D5 886 PUSH DE ; STORE DE - 887 ; COMPUTE STARTING ADDRESS OF CP/M SECTOR IN READ SECTOR BUFFER - 02AE 21rE2s0F 888 LD HL,#SECTOR_BUFFER ; LOAD HL WITH SECTOR BUFFER ADDRESS - 02B1 3Ar1Cs0B 889 LD A,(SECTOR_INDEX) ; GET THE SECTOR INDEX (CP/M SECTOR OFFSET IN BUFFER) - 02B4 0F 890 RRCA ; MOVE BIT 0 TO BIT 7 - 02B5 0F 891 RRCA ; DO AGAIN - IN EFFECT MULTIPLY BY 4 - 02B6 16 00 892 LD D,#0 ; PUT RESULT AS 16 VALUE IN DE, UPPER BYTE IN D IS 000h - 02B8 5F 893 LD E,A ; PUT ADDRESS OFFSET IN E - 02B9 19 894 ADD HL,DE ; MULTIPLY BY 2, TOTAL MULTIPLICATION IS X 128 - 02BA 19 895 ADD HL,DE ; CP/M SECTOR STARTING ADDRESS IN IDE HD SECTOR BUFFER - 896 ; COPY CP/M SECTOR TO BDOS DMA ADDRESS BUFFER - 02BB D1 897 POP DE ; RESTORE DE - 02BC CDr10s05 898 CALL COPY_CPM_SECTOR ; - 02BF C9 899 RET - 900 - 901 ;___BLKSEC_______________________________________________________________________________________________ - 902 ; - 903 ; BLOCK 512 BYTE SECTOR FOR CP/M - 904 ; - 905 ;________________________________________________________________________________________________________ - 02C0 906 BLKSEC: - 907 ; COMPUTE STARTING ADDRESS OF CP/M SECTOR IN READ SECTOR BUFFER - 02C0 21rE2s0F 908 LD HL,#SECTOR_BUFFER ; LOAD HL WITH SECTOR BUFFER ADDRESS - 02C3 3Ar1Cs0B 909 LD A,(SECTOR_INDEX) ; GET THE SECTOR INDEX (CP/M SECTOR OFFSET IN BUFFER) - 02C6 0F 910 RRCA ; MOVE BIT 0 TO BIT 7 - 02C7 0F 911 RRCA ; DO AGAIN - IN EFFECT MULTIPLY BY 64 - 02C8 16 00 912 LD D,#0 ; PUT RESULT AS 16 VALUE IN DE, UPPER BYTE IN D IS 000h - 02CA 5F 913 LD E,A ; PUT ADDRESS OFFSET IN E - 02CB 19 914 ADD HL,DE ; CP/M SECTOR STARTING ADDRESS IN IDE HD SECTOR BUFFER - 02CC 19 915 ADD HL,DE ; MULTIPLY BY 2, TOTAL MULTIPLICATION IS X 128 - 02CD 22r0Es0B 916 LD (SECST),HL ; KEEP CP/M SECTOR ADDRESS FOR LATER USE - 917 ; COPY CP/M SECTOR FROM BDOS DMA ADDRESS BUFFER - 02D0 2Ar0Es0B 918 LD HL,(SECST) ; LOAD CP/M SECTOR ADDRESS (WHERE THE DATA IS TO BE WRITTEN) - 02D3 54 919 LD D,H ; TRANSFER HL REGISTERS TO DE - 02D4 5D 920 LD E,L ; - 02D5 2Ar10s0B 921 LD HL,(DMAAD) ; LOAD HL WITH DMA ADDRESS (WHERE THE DATA TO BE WRITTEN IS) - 02D8 CDr10s05 922 CALL COPY_CPM_SECTOR ; - 02DB C9 923 RET - 924 - 925 ;___ISCUR_______________________________________________________________________________________________ - 926 ; - 927 ; IS CURRENT SECTOR IN BUFFER? - 928 ; - 929 ;________________________________________________________________________________________________________ - 02DC 930 ISCUR: - 02DC 2Ar0Cs0B 931 LD HL,(PSECTOR) ; COMPARE REQUESTED SECTOR WITH SECTOR IN BUFFER - 02DF 3ArDEs0F 932 LD A,(CUSECTOR) ; - 02E2 BD 933 CP L ; - 02E3 C0 934 RET NZ ; LOW BYTE NOT EQUAL - 02E4 3ArDFs0F 935 LD A,(CUSECTOR+1) ; - 02E7 BC 936 CP H ; - 02E8 C0 937 RET NZ ; HIGH BYTE NOT EQUAL - 02E9 2Ar04s0B 938 LD HL,(PTRACK) ; COMPARE REQUESTED TRACK WITH TRACK IN BUFFER - 02EC 3ArE0s0F 939 LD A,(CUTRACK) ; - 02EF BD 940 CP L ; LOW BYTE NOT EQUAL - 02F0 C0 941 RET NZ ; - 02F1 3ArE1s0F 942 LD A,(CUTRACK+1) ; - 02F4 BC 943 CP H ; - 02F5 C0 944 RET NZ ; HIGH BYTE NOT EQUAL - 02F6 2Ar12s0B 945 LD HL,(DISKNO) ; COMPARE REQUESTED DRIVE WITH DRIVE IN BUFFER - 02F9 3ArDDs0F 946 LD A,(CUDISK) ; - 02FC BD 947 CP L ; - 02FD C9 948 RET ; EXIT WITH RESULT - 949 - 950 ;___READ_FLPY_DSK________________________________________________________________________________________ - 951 ; - 952 ; READ FLOPPY DISK - 953 ; - 954 ;________________________________________________________________________________________________________ - 955 - 02FE 956 READ_FLPY_DSK: - 02FE F3 957 DI ; DISABLE INTERRUPTS - 02FF 21 00 00 958 LD HL,#0 ; - 0302 39 959 ADD HL,SP ; GET STACK POINTER INTO HL - 0303 22r64s0A 960 LD (PARKSTACK),HL ; SAVE STACK POINTER - 0306 31r63s0A 961 LD SP,#FLOPPYSTACK ; - 0309 CDr82s02 962 CALL TRFLSEC ; TRANSLATE SECTOR INFORMATION - 030C CDr1As03 963 CALL READ_FLPY_SEC ; - 030F CDrA8s02 964 CALL DEBSEC ; DEBLOCK SECTOR - 0312 3ArF7s0A 965 LD A,(ST1) ; LOAD RESULT CODE INTO A - 0315 966 READ_FLPY_DSK_EXIT: ; - 0315 ED 7Br64s0A 967 LD SP,(PARKSTACK) ; RETURN STACK - 968 ;;;;; EI ; RE-ENABLE INTERRUPTS - 0319 C9 969 RET - 970 - 971 - 972 ;___READ_FLPY_SEC________________________________________________________________________________________ - 973 ; - 974 ; READ A SECTOR FROM A FLOPPY DISK - 975 ; - 976 ;________________________________________________________________________________________________________ - 031A 977 READ_FLPY_SEC: - 031A 3E 00 978 LD A,#0 ; RESET STATUS FLAG 1 - 031C 32rF7s0A 979 LD (ST1),A ; - 031F CDrDCs02 980 CALL ISCUR ; IS CURRENT SECTOR ALREADY IN BUFFER - 0322 CAr65s03 981 JP Z,READ_FLPY_SEC_OK - 0325 3E 14 982 LD A,#20 ; 20 RETRIES - 0327 32rFFs0A 983 LD (RETRY),A ; - 032A 3E 02 984 LD A,#2 ; 2 ITERATIONS OF RETRIES - 032C 32r00s0B 985 LD (RETRY1),A ; - 032F 986 READ_FLPY_SEC_RETRY: ; - 032F CDr1Es08 987 CALL FLOPPYREAD ; READ THE FLOPPY DISK SECTOR - 0332 3ArF6s0A 988 LD A,(ST0) ; GET STATUS FLAG 0 - 0335 E6 F8 989 AND #0x0F8 ; MASK OF DRIVE AND HEAD SELECTION - 0337 47 990 LD B,A ; MOVE STATUS FLAG 0 TO B - 0338 3ArF7s0A 991 LD A,(ST1) ; GET STATUS FLAG 1 - 033B B0 992 OR B ; IF ZERO READ WAS OK - 033C CAr65s03 993 JP Z,READ_FLPY_SEC_OK - 033F 3ArFFs0A 994 LD A,(RETRY) ; READ NOT OK, DEC RETRY COUNTER - 0342 3D 995 DEC A ; - 0343 32rFFs0A 996 LD (RETRY),A ; STORE NEW RETRY COUNTER - 0346 C2r2Fs03 997 JP NZ,READ_FLPY_SEC_RETRY - 0349 CDr61s09 998 CALL CYCLEFLOPPY ; CYCLE FLOPPY HEAD - 034C 3E 14 999 LD A,#20 ; RESET TO 20 RETRIES - 034E 32rFFs0A 1000 LD (RETRY),A ; STORE RETRY COUNTER - 0351 3Ar00s0B 1001 LD A,(RETRY1) ; DEC RETRY ITERATION COUNTER - 0354 3D 1002 DEC A ; - 0355 32r00s0B 1003 LD (RETRY1),A ; - 0358 C2r2Fs03 1004 JP NZ,READ_FLPY_SEC_RETRY - 035B 21 FF FF 1005 LD HL,#0x0FFFF ; SET INVALID CONDITION, BUFFER IS INVALID - 035E 22rDEs0F 1006 LD (CUSECTOR),HL ; CURRENT PHYSICAL DISK SECTOR IN BUFFER - 0361 22rE0s0F 1007 LD (CUTRACK),HL ; CURRENT PHYSICAL DISK TRACK IN BUFFER - 0364 C9 1008 RET ; - 0365 1009 READ_FLPY_SEC_OK: ; - 0365 2Ar0Cs0B 1010 LD HL,(PSECTOR) ; STORE PHYSICAL SECTOR IN BUFFER - 0368 22rDEs0F 1011 LD (CUSECTOR),HL ; - 036B 2Ar04s0B 1012 LD HL,(PTRACK) ; STORE PHYSICAL DISK TRACK IN BUFFER - 036E 22rE0s0F 1013 LD (CUTRACK),HL ; - 0371 3Ar12s0B 1014 LD A,(DISKNO) ; STORE CURRENT DRIVE IN BUFFER - 0374 32rDDs0F 1015 LD (CUDISK),A ; - 0377 C9 1016 RET - 1017 - 1018 ;___READ_IDE_____________________________________________________________________________________________ - 1019 ; - 1020 ; READ FROM IDE HARD DISK - 1021 ;________________________________________________________________________________________________________ - 1022 - 0378 1023 READ_IDE: - 0378 F3 1024 DI ; DISABLE INTERRUPTS - 0379 21 00 00 1025 LD HL,#0 ; - 037C 39 1026 ADD HL,SP ; GET STACK POINTER INTO HL - 037D 22r64s0A 1027 LD (PARKSTACK),HL ; SAVE STACK POINTER - 0380 31r63s0A 1028 LD SP,#FLOPPYSTACK ; - 1029 ; DISABLE INTERRUPTS - 0383 CDr16s05 1030 CALL CONVERT_IDE_SECTOR_CPM - 0386 CDr6As05 1031 CALL IDE_READ_SECTOR ; READ THE IDE HARD DISK SECTOR - 0389 D2r96s03 1032 JP NC,READ_IDE_ERROR - 038C CDrA8s02 1033 CALL DEBSEC ; - 038F ED 7Br64s0A 1034 LD SP,(PARKSTACK) ; RETURN STACK - 1035 ;;;;; EI ; RE-ENABLE INTERRUPTS - 0393 3E 00 1036 LD A,#0 ; RETURN ERROR CODE READ SUCCESSFUL A=0 - 0395 C9 1037 RET ; - 0396 1038 READ_IDE_ERROR: ; - 0396 ED 7Br64s0A 1039 LD SP,(PARKSTACK) ; RETURN STACK - 1040 ;;;;; EI ; RE-ENABLE INTERRUPTS - 039A 3E FF 1041 LD A,#0x0FF ; RETURN ERROR CODE READ ERROR A=FF - 039C C9 1042 RET - 1043 - 1044 ;___READ_ATAPI_________________________________________________________________________________________ - 1045 ; - 1046 ; READ FROM ATAPI DEVICE - 1047 ;________________________________________________________________________________________________________ - 039D 1048 READ_ATAPI: - 039D 3E FF 1049 LD A,#0x0FF ; 255 RETRIES - 039F 32rFFs0A 1050 LD (RETRY),A ; - 03A2 1051 READ_ATAPI_RETRY: - 03A2 3E 10 1052 LD A,#0x10 ; SET TO SECONDARY DEVICE - 03A4 32r17s0B 1053 LD (IDEDEVICE),A ; - 03A7 F3 1054 DI ; DISABLE INTERRUPTS - 03A8 21 00 00 1055 LD HL,#0 ; - 03AB 39 1056 ADD HL,SP ; GET STACK POINTER INTO HL - 03AC 22r64s0A 1057 LD (PARKSTACK),HL ; SAVE STACK POINTER - 03AF 31r63s0A 1058 LD SP,#FLOPPYSTACK ; - 03B2 CDr16s05 1059 CALL CONVERT_IDE_SECTOR_CPM - 03B5 CDrDFs06 1060 CALL ATAPI_READ_SECTOR - 03B8 D2rC5s03 1061 JP NC,READ_ATAPI_ERROR - 03BB CDrA8s02 1062 CALL DEBSEC ; - 03BE ED 7Br64s0A 1063 LD SP,(PARKSTACK) ; RETURN STACK - 1064 ;;;;; EI ; RE-ENABLE INTERRUPTS - 03C2 3E 00 1065 LD A,#0 ; RETURN ERROR CODE READ SUCCESSFUL A=0 - 03C4 C9 1066 RET ; - 03C5 1067 READ_ATAPI_ERROR: - 03C5 3ArFFs0A 1068 LD A,(RETRY) ; READ NOT OK, DEC RETRY COUNTER - 03C8 3D 1069 DEC A ; - 03C9 32rFFs0A 1070 LD (RETRY),A ; STORE NEW RETRY COUNTER - 03CC C2rA2s03 1071 JP NZ,READ_ATAPI_RETRY - 03CF ED 7Br64s0A 1072 LD SP,(PARKSTACK) ; RETURN STACK - 1073 ;;;;; EI ; RE-ENABLE INTERRUPTS - 03D3 3E FF 1074 LD A,#0x0FF ; RETURN ERROR CODE READ ERROR A=FF - 03D5 C9 1075 RET ; - 1076 - 03D6 1077 READ_HDPART4: - 1078 ; STUB - 03D6 C9 1079 RET - 1080 - 1081 ;___WRITE______________________________________________________________________________________________ - 1082 ; - 1083 ; HANDLE CP/M WRITE CALL - 1084 ; - 1085 ;________________________________________________________________________________________________________ - 03D7 1086 WRITE: - 03D7 F3 1087 DI ; DISABLE INTERRUPTS - 03D8 3Ar12s0B 1088 LD A,(DISKNO) ; GET DRIVE - 03DB FE 01 1089 CP #1 ; FIND OUT WHICH DRIVE IS BEING REQUESTED - 0001 1090 .IF CONDUSEFLOPPY - 03DD CAr25s04 1091 JP Z,WRITE_FLP_DSK ; - 1092 .ELSE - 1093 JP Z,WRITE_RAM_DISK ; WRITE TO 448K RAM DISK - 1094 .ENDIF - 03E0 FE 00 1095 CP #0 ; - 03E2 CArFDs03 1096 JP Z,WRITE_RAM_DISK ; WRITE TO 448K RAM DISK - 03E5 FE 02 1097 CP #2 ; - 03E7 CAr66s04 1098 JP Z,WRITE_IDE ; WRITE TO 8 MB IDE HARD DISK, PARTITION 2 - 03EA FE 03 1099 CP #3 ; - 0000 1100 .IF CONDUSEATAPI - 1101 JP Z,WRITE_ATAPI ; WRITE TO 8 MB IDE HARD DISK, PARTITION 3 - 1102 .ELSE - 03EC CArFDs03 1103 JP Z,WRITE_RAM_DISK ; WRITE TO 448K RAM DISK - 1104 .ENDIF - 03EF FE 04 1105 CP #4 ; - 03F1 CArBBs04 1106 JP Z,WRITE_HDPART4 ; WRITE TO 1 MB IDE HARD DISK, PARTITION 4 - 1107 - 1108 - 1109 ;___RDONLY______________________________________________________________________________________________ - 1110 ; - 1111 ; HANDLE WRITE TO READ ONLY - 1112 ; - 1113 ; SENDS A MESSAGE TO TERMINAL THAT ROM DRIVE IS NOT WRITEABLE - 1114 ; DOES A PAUSE THEN RETURNS TO CPM WITH ERROR FLAGGED THIS IS - 1115 ; DONE TO ALLOW A POSSIBLE GRACEFUL EXIT (SOME APPS MAY PUKE) - 1116 ;________________________________________________________________________________________________________ - 03F4 1117 RDONLY: - 03F4 21r8Cs0A 1118 LD HL,#TXT_RO_ERROR ; SET HL TO START OF ERROR MESSAGE - 03F7 CDrBCs04 1119 CALL PRTMSG ; PRINT ERROR MESSAGE - 03FA 3E 01 1120 LD A,#1 ; SEND BAD SECTOR ERROR BACK - 1121 ; BDOS WILL ALSO PRINT ITS OWN ERROR MESSAGE - 03FC C9 1122 RET - 1123 - 1124 ;___WRITE_RAM_DISK_____________________________________________________________________________________ - 1125 ; - 1126 ; WRITE RAM DISK - 1127 ;________________________________________________________________________________________________________ - 03FD 1128 WRITE_RAM_DISK: - 03FD 21rE2s0F 1129 LD HL,#SECTOR_BUFFER ; LOAD HL WITH TEMP BUF ADDRESS - 0400 5D 1130 LD E,L ; - 0401 54 1131 LD D,H ; GET IT INTO DE - 0402 2Ar10s0B 1132 LD HL,(DMAAD) ; GET DMA ADDRESS - 0405 CDr10s05 1133 CALL COPY_CPM_SECTOR ; - 0408 CDrCBs04 1134 CALL SECPAGE ; GET RAM PAGE WRITE ADDRESS - 040B CDrD9s04 1135 CALL PAGERB ; SET PAGER WITH DRIVE AND TRACK - 040E 2Ar0Es0B 1136 LD HL,(SECST) ; LOAD HL WITH DMA ADDRESS (WHERE TO WRITE TO) - 0411 5D 1137 LD E,L ; - 0412 54 1138 LD D,H ; GET IT INTO DE - 0413 21rE2s0F 1139 LD HL,#SECTOR_BUFFER ; GET TEMP BUFFER ADDRESS - 0416 CDr10s05 1140 CALL COPY_CPM_SECTOR ; - 0419 CDr04s05 1141 CALL RPAGE ; SET BACK TO RAM - 041C 3Ar12s0B 1142 LD A,(DISKNO) ; STORE CURRENT DRIVE IN BUFFER - 041F 32rDDs0F 1143 LD (CUDISK),A ; - 0422 3E 00 1144 LD A,#0 ; - 1145 ;;;;; EI ; RE-ENABLE INTERRUPTS - 0424 C9 1146 RET - 1147 - 1148 ;___WRITE_FLP_DSK_____________________________________________________________________________________ - 1149 ; - 1150 ; WRITE FLOPPY DISK - 1151 ;________________________________________________________________________________________________________ - 0425 1152 WRITE_FLP_DSK: - 0425 F3 1153 DI ; DISABLE INTERRUPTS - 0426 21 00 00 1154 LD HL,#0 ; - 0429 39 1155 ADD HL,SP ; MOVE STACK POINTER TO HL - 042A 22r64s0A 1156 LD (PARKSTACK),HL ; SAVE STACK POINTER - 042D 31r63s0A 1157 LD SP,#FLOPPYSTACK ; - 0430 CDr82s02 1158 CALL TRFLSEC ; TRANSLATE SECTOR INFORMATION - 0433 CDr1As03 1159 CALL READ_FLPY_SEC ; - 0436 3ArF7s0A 1160 LD A,(ST1) ; GET STATUS CODE - 0439 C2r5Es04 1161 JP NZ,WRITE_FLP_DSK_OK - 043C 1162 WRITE_READ_FLPY_DSK_OK: ; - 043C CDrC0s02 1163 CALL BLKSEC ; BLOCK SECTOR - 1164 ; IDE HD SECTOR IS NOW UPDATED WITH CURRENT CP/M SECTOR DATA SO WRITE TO DISK - 043F 3E 14 1165 LD A,#20 ; 20 RETRIES - 0441 32rFFs0A 1166 LD (RETRY),A ; - 0444 1167 WRITE_FLP_DSK_RETRY: ; - 0444 CDr26s08 1168 CALL FLOPPYWRITE ; WRITE THE FLOPPY DISK SECTOR - 0447 3ArF6s0A 1169 LD A,(ST0) ; GET STATUS CODE 0 - 044A E6 F8 1170 AND #0x0F8 ; MASK OF DRIVE AND HEAD SELECTION - 044C 47 1171 LD B,A ; MOVE STATUS CODE 0 TO B - 044D 3ArF7s0A 1172 LD A,(ST1) ; GET STATUS CODE 1 - 0450 B0 1173 OR B ; IF ZERO WRITE WAS OK - 0451 CAr5Es04 1174 JP Z,WRITE_FLP_DSK_OK ; - 0454 3ArFFs0A 1175 LD A,(RETRY) ; BAD WRITE, DEC RETRY COUNTER - 0457 3D 1176 DEC A ; - 0458 32rFFs0A 1177 LD (RETRY),A ; STORE NEW RETRY COUNTER - 045B C2r44s04 1178 JP NZ,WRITE_FLP_DSK_RETRY ; - 045E 1179 WRITE_FLP_DSK_OK: ; - 045E ED 7Br64s0A 1180 LD SP,(PARKSTACK) ; RESTORE STACK - 0462 3ArF7s0A 1181 LD A,(ST1) ; GET STATUS CODE 1 - 1182 ;;;;; EI ; RE-ENABLE INTERRUPTS - 0465 C9 1183 RET - 1184 - 1185 - 1186 - 1187 ;___WRITE_IDE____________________________________________________________________________________________ - 1188 ; - 1189 ; WRITE TO IDE DEVICE - 1190 ;________________________________________________________________________________________________________ - 0466 1191 WRITE_IDE: - 0466 F3 1192 DI ; DISABLE INTERRUPTS - 0467 21 00 00 1193 LD HL,#0 ; - 046A 39 1194 ADD HL,SP ; GET STACK POINTER INTO HL - 046B 22r64s0A 1195 LD (PARKSTACK),HL ; SAVE STACK POINTER - 046E 31r63s0A 1196 LD SP,#FLOPPYSTACK ; - 0471 CDr16s05 1197 CALL CONVERT_IDE_SECTOR_CPM ; - 0474 CDr6As05 1198 CALL IDE_READ_SECTOR ; READ THE IDE HARD DISK SECTOR - 0477 D2r87s04 1199 JP NC,WRITE_IDE_ERROR ; - 047A CDrC0s02 1200 CALL BLKSEC ; DEBLOCK SECTOR - 047D CDr9Fs05 1201 CALL IDE_WRITE_SECTOR ; WRITE THE UPDATED IDE HARD DISK SECTOR - 0480 ED 7Br64s0A 1202 LD SP,(PARKSTACK) ; RESTORE STACK - 1203 ;;;;; EI ; RE-ENABLE INTERRUPTS - 0484 3E 00 1204 LD A,#0 ; RETURN ERROR CODE WRITE SUCCESSFUL A=0 - 0486 C9 1205 RET ; - 0487 1206 WRITE_IDE_ERROR: ; - 0487 ED 7Br64s0A 1207 LD SP,(PARKSTACK) ; RESTORE STACK - 1208 ;;;;; EI ; RE-ENABLE INTERRUPTS - 048B 3E FF 1209 LD A,#0x0FF ; RETURN ERROR CODE WRITE ERROR A=FF - 048D C9 1210 RET - 1211 - 1212 ;___WRITE_ATAPI__________________________________________________________________________________________ - 1213 ; - 1214 ; WRITE TO ATAPI DEVICE - 1215 ;________________________________________________________________________________________________________ - 048E 1216 WRITE_ATAPI: - 048E 3E 10 1217 LD A,#0x10 ; SET TO SECONDARY DEVICE - 0490 32r17s0B 1218 LD (IDEDEVICE),A ; - 0493 F3 1219 DI ; DISABLE INTERRUPTS - 0494 21 00 00 1220 LD HL,#0 ; - 0497 39 1221 ADD HL,SP ; GET STACK POINTER INTO HL - 0498 22r64s0A 1222 LD (PARKSTACK),HL ; SAVE STACK POINTER - 049B 31r63s0A 1223 LD SP,#FLOPPYSTACK ; - 1224 ; - 049E CDr16s05 1225 CALL CONVERT_IDE_SECTOR_CPM ; - 1226 ; - 04A1 CDrDFs06 1227 CALL ATAPI_READ_SECTOR ; - 04A4 D2rB4s04 1228 JP NC,WRITE_ATAPI_ERROR ; - 04A7 CDrC0s02 1229 CALL BLKSEC ; DEBLOCK SECTOR - 04AA CDr3Cs07 1230 CALL ATAPI_WRITE_SECTOR ; - 1231 ; - 04AD ED 7Br64s0A 1232 LD SP,(PARKSTACK) ; RESTORE STACK - 1233 ;;;;; EI ; RE-ENABLE INTERRUPTS - 04B1 3E 00 1234 LD A,#0 ; RETURN ERROR CODE WRITE SUCCESSFUL A=0 - 04B3 C9 1235 RET ; - 04B4 1236 WRITE_ATAPI_ERROR: ; - 04B4 ED 7Br64s0A 1237 LD SP,(PARKSTACK) ; RESTORE STACK - 1238 ;;;;; EI ; RE-ENABLE INTERRUPTS - 04B8 3E FF 1239 LD A,#0x0FF ; RETURN ERROR CODE WRITE ERROR A=FF - 04BA C9 1240 RET ; - 1241 - 04BB 1242 WRITE_HDPART4: - 1243 ; STUB - 04BB C9 1244 RET - 1245 - 1246 - 1247 ;___PRTMSG_______________________________________________________________________________________________ - 1248 ; - 1249 ; PRINT MESSAGE POINTED TO BY HL ON CONSOLE DEVICE - 1250 ;________________________________________________________________________________________________________ - 04BC 1251 PRTMSG: - 04BC 7E 1252 LD A,(HL) ; GET CHARACTER TO A - 04BD FE FF 1253 CP #END ; TEST FOR END BYTE - 04BF CArCAs04 1254 JP Z,PRTMSG1 ; JUMP IF END BYTE IS FOUND - 04C2 4F 1255 LD C,A ; PUT CHAR TO PRINT VALUE IN REG C FOR CONOUT - 04C3 CDrB1s01 1256 CALL CONOUT ; SEND CHARACTER TO CONSOLE FROM REG C - 04C6 23 1257 INC HL ; INC POINTER, TO NEXT CHAR - 04C7 C3rBCs04 1258 JP PRTMSG ; TRANSMIT LOOP - 04CA 1259 PRTMSG1: - 04CA C9 1260 RET - 1261 - 1262 - 1263 ;___SECPAGE_______________________________________________________________________________________________ - 1264 ; - 1265 ; UTILITY ROUTINE FOR SECTOR TO PAGE ADDRESS - 1266 ;________________________________________________________________________________________________________ - 04CB 1267 SECPAGE: - 04CB 2Ar0As0B 1268 LD HL,(SECTOR) ; GET SECTOR INTO HL - 04CE 29 1269 ADD HL,HL ; SHIFT BITS 1 TO LEFT (*2) - 04CF 29 1270 ADD HL,HL ; SHIFT BITS 1 TO LEFT (*4) - 04D0 29 1271 ADD HL,HL ; SHIFT BITS 1 TO LEFT (*8) - 04D1 29 1272 ADD HL,HL ; SHIFT BITS 1 TO LEFT (*16) - 04D2 29 1273 ADD HL,HL ; SHIFT BITS 1 TO LEFT (*32) - 04D3 29 1274 ADD HL,HL ; SHIFT BITS 1 TO LEFT (*64) - 04D4 29 1275 ADD HL,HL ; SHIFT BITS 1 TO LEFT (*128) - 04D5 22r0Es0B 1276 LD (SECST),HL ; SAVE SECTOR STARTING ADDRESS - 04D8 C9 1277 RET - 1278 - 1279 ;___PAGERB_______________________________________________________________________________________________ - 1280 ; - 1281 ; PAGER BYTE CREATION - 1282 ; ASSEMBLES DRIVE AND TRACK AND SENDS IT TO PAGER PORT - 1283 ;________________________________________________________________________________________________________ - 04D9 1284 PAGERB: - 04D9 2Ar02s0B 1285 LD HL,(TRACK) ; LOAD TRACK INTO HL - 04DC 3Ar12s0B 1286 LD A,(DISKNO) ; LOAD DISK INTO A - 04DF FE 05 1287 CP #5 ; IS ROM? - 04E1 CArF3s04 1288 JP Z,ROMD ; READ FROM 1M ROM DISK - 04E4 FE 06 1289 CP #6 ; IS ROM? - 04E6 CArF3s04 1290 JP Z,ROMD ; READ FROM 22K ROM DISK - 04E9 E6 01 1291 AND #1 ; MASK FOR 1 BIT OF DRIVE SELECT - 04EB 0F 1292 RRCA ; MOVE BIT 0 TO BIT 7 - 04EC B5 1293 OR L ; OR L WITH ACC TO COMBINE TRACK AND DRIVE - 04ED D3 78 1294 OUT (MPCL_RAM),A ; SEND TO RAM PORT MAPPER - 04EF 32r08s0B 1295 LD (PAGER),A ; SAVE COPY (JUST BECAUSE) - 04F2 C9 1296 RET ; - 04F3 1297 ROMD: ; - 04F3 3E 05 1298 LD A,#5 ; - 04F5 E6 01 1299 AND #1 ; MASK FOR 1 BIT OF DRIVE SELECT - 04F7 0F 1300 RRCA ; MOVE BIT 0 TO BIT 7 - 04F8 B5 1301 OR L ; OR L WITH ACC TO COMBINE TRACK AND DRIVE - 04F9 E6 7F 1302 AND #0x7F ; STRIP OFF BIT 7 (ROM_ENABLE BIT) - 04FB D3 7C 1303 OUT (MPCL_ROM),A ; SEND TO ROM PORT MAPPER - 04FD 32r08s0B 1304 LD (PAGER),A ; SAVE COPY (JUST BECAUSE) - 0500 32r09s0B 1305 LD (DB_PAGER),A ; SAVE COPY (JUST BECAUSE) (DEBUG) - 0503 C9 1306 RET - 1307 - 1308 ;___RPAGE_______________________________________________________________________________________________ - 1309 ; - 1310 ; RESET PAGER BACK TO RAM - 1311 ;________________________________________________________________________________________________________ - 0504 1312 RPAGE: - 0504 3E 80 1313 LD A,#0x80 ; DESELECT ROM PAGE - 0506 D3 7C 1314 OUT (MPCL_ROM),A ; SELECT RAM - 0508 3E 00 1315 LD A,#0 ; SET TO RAM, TRACK 0 - 050A D3 78 1316 OUT (MPCL_RAM),A ; SELECT RAM - 050C 32r08s0B 1317 LD (PAGER),A ; SAVE COPY OF PAGER BYTE - 050F C9 1318 RET - 1319 - 1320 ;___COPY_CPM_SECTOR______________________________________________________________________________________ - 1321 ; - 1322 ; COPIES ONE CPM SECTOR FROM ONE MEMORY ADDRESS TO ANOTHER - 1323 ; INPUT - 1324 ; DE SOURCE ADDRESS - 1325 ; HL TARGET ADDRESS - 1326 ; USES C REGISTER - 1327 ;________________________________________________________________________________________________________ - 0510 1328 COPY_CPM_SECTOR: - 0510 01 80 00 1329 LD BC,#128 ; BC IS COUNTER FOR FIXED SIZE TRANSFER (128 BYTES) - 0513 ED B0 1330 LDIR ; TRANSFER - 0515 C9 1331 RET - 1332 - 1333 ;___CONVERT_IDE_SECTOR_CPM________________________________________________________________________________ - 1334 ; - 1335 ; COMPUTES WHERE THE CP/M SECTOR IS IN THE LBA PARTITION - 1336 ; LBA HD SECTORS ARE 512 BYTES EACH, CP/M SECTORS ARE 128 BYTES EACH - 1337 ; MAXIMUM SIZE OF CP/M DISK IS 8 MB = 65536 (16 BITS) X 128 BYTES PER SECTOR - 1338 ; LBA HD PARTITION CAN HAVE AT MOST 16777215 IDE SECTORS -> 67108860 CP/M SECTORS - 1339 ; EACH IDE HD SECTOR CONTAINS 4 ADJACENT CP/M SECTORS - 1340 ; - 1341 ; - 1342 ; INPUT: - 1343 ; - CP/M TRACK AND SECTOR 16 BIT WORDS - 1344 ; - 1345 ; OUTPUT: - 1346 ; IDE TARGET SECTOR (SENT TO IDE HD CONTROLLER FOR READ OPERATION) - 1347 ; - LOWER 16 BITS STORED IN LBA_TARGET_LO - 1348 ; - UPPER 16 BITS STORED IN LBA_TARGET_HI - 1349 ; CP/M TO IDE HD SECTOR MAPPING PARAMETER STORED IN SECTOR_INDEX - 1350 ; - 8 BIT VALUE WITH 4 LEGAL STATES (00, 01, 02, 04) WHICH IS - 1351 ; TO BE USED TO COMPUTE STARTING ADDRESS OF 128 BYTE CP/M SECTOR ONCE - 1352 ; 512 BYTE IDE HD SECTOR READ INTO MEMORY BUFFER - 1353 ; LBA ADDRESS FORMAT = 00TTTTSS - 1354 ; - 1355 ; ROTATE WITH CARRY 16 BIT TRACK,SECTOR VALUE IN HL TO GET 14 BIT IDE HD - 1356 ; TARGET SECTOR IN PARTITION - 1357 ; KEEP LAST TWO BITS IN B FOR IDE HD SECTOR TO CP/M SECTOR TRANSLATION - 1358 ; COMPUTE SECTOR_INDEX - 1359 ;________________________________________________________________________________________________________ - 0516 1360 CONVERT_IDE_SECTOR_CPM: - 1361 - 0516 3Ar02s0B 1362 LD A,(TRACK) ; LOAD TRACK # (LOW BYTE) - 0519 67 1363 LD H,A ; - 051A 3Ar0As0B 1364 LD A,(SECTOR) ; LOAD SECTOR# (LOW BYTE) - 051D 6F 1365 LD L,A ; - 051E CDr61s05 1366 CALL RRA16 ; ROTATE 'HL' RIGHT (DIVIDE BY 2) - 0521 CDr61s05 1367 CALL RRA16 ; ROTATE 'HL' RIGHT (DIVIDE BY 2) - 0524 3Ar03s0B 1368 LD A,(TRACK+1) ; GET HIGH BYTE OF TRACK INTO A - 0527 CB 27 1369 SLA A ; - 0529 CB 27 1370 SLA A ; - 052B CB 27 1371 SLA A ; - 052D CB 27 1372 SLA A ; - 052F CB 27 1373 SLA A ; - 0531 CB 27 1374 SLA A ; - 0533 B4 1375 OR H ; - 0534 67 1376 LD H,A ; - 0535 3Ar03s0B 1377 LD A,(TRACK+1) ; GET HIGH BYTE OF TRACK INTO A - 0538 CB 3F 1378 SRL A ; - 053A CB 3F 1379 SRL A ; - 053C 32r15s0B 1380 LD (LBA_TARGET_HI),A ; - 053F 7D 1381 LD A,L ; - 0540 32r13s0B 1382 LD (LBA_TARGET_LO),A ; LBA REGISTER IS 00TTTTSS / 4 - 0543 7C 1383 LD A,H ; - 0544 32r14s0B 1384 LD (LBA_TARGET_LO+1),A ; - 0547 3E 00 1385 LD A,#0 ; - 0549 32r16s0B 1386 LD (LBA_TARGET_HI+1),A ; - 1387 ; - 054C 2Ar13s0B 1388 LD HL,(LBA_TARGET_LO) ; STORE PHYSICAL SECTOR - 054F 22r0Cs0B 1389 LD (PSECTOR),HL ; - 0552 2Ar15s0B 1390 LD HL,(LBA_TARGET_HI) ; STORE PHYSICAL TRACK - 0555 22r04s0B 1391 LD (PTRACK),HL ; - 0558 3Ar0As0B 1392 LD A,(SECTOR) ; LOAD SECTOR # - 055B E6 03 1393 AND #0b000000011 ; - 055D 32r1Cs0B 1394 LD (SECTOR_INDEX),A ; LOCATES WHERE THE 128 BYTE CP/M SECTOR - 1395 ; IS WITHIN THE 512 BYTE IDE HD SECTOR - 1396 ; COMPUTE WHICH IDE HD SECTOR TO READ TO WITHIN 4 CP/M SECTORS - 1397 ; SHIFTS 16 BIT PARTITION OFFSET TO THE RIGHT 2 BITS AND ADDS RESULT TO - 1398 ; IDE HD PARTITION STARTING SECTOR - 1399 ; SHIFT PARTITION OFFSET RIGHT 1 BIT - 0560 C9 1400 RET - 0561 1401 RRA16: - 0561 37 1402 SCF ; - 0562 3F 1403 CCF ; CLEAR CARRY FLAG - 0563 7C 1404 LD A,H ; 16 BIT ROTATE HL WITH CARRY - 0564 1F 1405 RRA ; - 0565 67 1406 LD H,A ; ROTATE HL RIGHT 1 BIT (DIVIDE BY 2) - 0566 7D 1407 LD A,L ; - 0567 1F 1408 RRA ; - 0568 6F 1409 LD L,A ; - 0569 C9 1410 RET - 1411 - 1412 - 1413 ;___IDE_READ_SECTOR______________________________________________________________________________________ - 1414 ; - 1415 ; READ IDE SECTOR - 1416 ;________________________________________________________________________________________________________ - 056A 1417 IDE_READ_SECTOR: - 056A CDrDCs02 1418 CALL ISCUR ; IS CURRENT SECTOR IN BUFFER? - 056D CAr8Bs05 1419 JP Z,IDE_READ_SECTOR_OK ; - 0570 CDrF3s05 1420 CALL IDE_WAIT_BUSY_READY ; MAKE SURE DRIVE IS READY TO PROCEED - 0573 D0 1421 RET NC ; ERROR, RETURN - 0574 CDr66s06 1422 CALL IDE_SETUP_LBA ; TELL DRIVE WHAT SECTOR IS REQUIRED - 0577 3E 20 1423 LD A,#0x20 ; - 0579 D3 27 1424 OUT (IDESTTS),A ; 020h = IDE 'READ SECTOR' COMMAND - 057B 1425 IDE_SREX: ; - 057B CDrF3s05 1426 CALL IDE_WAIT_BUSY_READY ; MAKE SURE DRIVE IS READY TO PROCEED - 057E D0 1427 RET NC ; ERROR, RETURN - 057F CDr0Fs06 1428 CALL IDE_TEST_ERROR ; ENSURE NO ERROR WAS REPORTED - 0582 D0 1429 RET NC ; ERROR, RETURN - 0583 CDr22s06 1430 CALL IDE_WAIT_BUFFER ; WAIT FOR FULL BUFFER SIGNAL FROM DRIVE - 0586 D0 1431 RET NC ; ERROR, RETURN - 0587 CDr3Cs06 1432 CALL IDE_READ_BUFFER ; GRAB THE 256 WORDS FROM THE BUFFER - 058A 37 1433 SCF ; CARRY = 1 ON RETURN = OPERATION OK - 058B 1434 IDE_READ_SECTOR_OK: ; - 058B 2Ar0Cs0B 1435 LD HL,(PSECTOR) ; STORE PHYSICAL SECTOR IN BUFFER - 058E 22rDEs0F 1436 LD (CUSECTOR),HL ; - 0591 2Ar04s0B 1437 LD HL,(PTRACK) ; STORE PHYSICAL DISK TRACK IN BUFFER - 0594 22rE0s0F 1438 LD (CUTRACK),HL ; - 0597 3Ar12s0B 1439 LD A,(DISKNO) ; STORE CURRENT DRIVE IN BUFFER - 059A 32rDDs0F 1440 LD (CUDISK),A ; - 059D 37 1441 SCF ; CARRY = 1 ON RETURN = OPERATION OK - 059E C9 1442 RET - 1443 - 1444 ;___IDE_WRITE_SECTOR_____________________________________________________________________________________ - 1445 ; - 1446 ; WRITE IDE SECTOR - 1447 ;________________________________________________________________________________________________________ - 059F 1448 IDE_WRITE_SECTOR: - 059F CDrF3s05 1449 CALL IDE_WAIT_BUSY_READY ; MAKE SURE DRIVE IS READY TO PROCEED - 05A2 D0 1450 RET NC ; ERROR, RETURN - 05A3 CDr66s06 1451 CALL IDE_SETUP_LBA ; TELL DRIVE WHAT SECTOR IS REQUIRED - 05A6 3E 30 1452 LD A,#0x30 ; - 05A8 D3 27 1453 OUT (IDESTTS),A ; 030h = IDE 'WRITE SECTOR' COMMAND - 05AA CDrF3s05 1454 CALL IDE_WAIT_BUSY_READY ; - 05AD D0 1455 RET NC ; ERROR, RETURN - 05AE CDr0Fs06 1456 CALL IDE_TEST_ERROR ; ENSURE NO ERROR WAS REPORTED - 05B1 D0 1457 RET NC ; ERROR, RETURN - 05B2 CDr22s06 1458 CALL IDE_WAIT_BUFFER ; WAIT FOR BUFFER READY SIGNAL FROM DRIVE - 05B5 D0 1459 RET NC ; ERROR, RETURN - 05B6 CDr50s06 1460 CALL IDE_WRITE_BUFFER ; SEND 256 WORDS TO DRIVE'S BUFFER - 05B9 CDrF3s05 1461 CALL IDE_WAIT_BUSY_READY ; MAKE SURE DRIVE IS READY TO PROCEED - 05BC D0 1462 RET NC ; ERROR, RETURN - 05BD CDr0Fs06 1463 CALL IDE_TEST_ERROR ; ENSURE NO ERROR WAS REPORTED - 05C0 D0 1464 RET NC ; ERROR, RETURN - 05C1 37 1465 SCF ; CARRY = 1 ON RETURN = OPERATION OK - 05C2 C9 1466 RET - 1467 - 1468 ;___IDE_SOFT_RESET_______________________________________________________________________________________ - 1469 ; - 1470 ; RESET IDE CHANNEL - 1471 ;________________________________________________________________________________________________________ - 05C3 1472 IDE_SOFT_RESET: - 0001 1473 .IF CONDIDESOFT ; - 05C3 3E 06 1474 LD A,#0b000000110 ; NO INTERRUPTS, RESET DRIVE = 1 - 05C5 D3 2E 1475 OUT (IDECTRL),A ; - 05C7 3E 02 1476 LD A,#0b000000010 ; NO INTERRUPTS, RESET DRIVE = 0 - 05C9 D3 2E 1477 OUT (IDECTRL),A ; - 05CB CDrF3s05 1478 CALL IDE_WAIT_BUSY_READY ;THIS TAKES A COUPLE OF SECONDS - 05CE C9 1479 RET - 1480 .ELSE - 1481 ; SKIP THIS IF NO IDE DRIVE WHICH SPEEDS UP REBOOTS AND STARTUPS - 1482 RET - 1483 .ENDIF - 1484 - 1485 ;___ATAPI_WAIT_BUSY_READY________________________________________________________________________________ - 1486 ; - 1487 ; WAIT FOR ATAPI CHANNEL TO BE READY - 1488 ;________________________________________________________________________________________________________ - 05CF 1489 ATAPI_WAIT_BUSY_READY: - 05CF 11 00 00 1490 LD DE,#0 ; CLEAR OUT DE - 05D2 1491 ATAPI_WBSY: ; - 05D2 06 F0 1492 LD B,#0x0F0 ; SETUP TIMEOUT - 05D4 1493 ATAPI_DLP: ; - 05D4 10 FE 1494 DJNZ ATAPI_DLP ; - 05D6 13 1495 INC DE ; - 05D7 7A 1496 LD A,D ; - 05D8 B3 1497 OR E ; - 05D9 28 08 1498 JR Z,ATAPI_TO ; - 05DB DB 27 1499 IN A,(IDESTTS) ; READ ERROR REG - 05DD E6 80 1500 AND #0b010000000 ; MASK OFF BUSY BIT - 05DF 20 F1 1501 JR NZ,ATAPI_WBSY ; WE WANT BUSY(7) TO BE 0 - 05E1 37 1502 SCF ; CARRY 1 = OK - 05E2 C9 1503 RET ; - 05E3 1504 ATAPI_TO: ; - 05E3 AF 1505 XOR A ; CARRY 0 = TIMED OUT - 05E4 C9 1506 RET ; - 1507 - 1508 ;___IDE_WAIT_DRQ_READY___________________________________________________________________________________ - 1509 ; - 1510 ; WAIT FOR IDE CHANNEL TO BE READY - 1511 ;________________________________________________________________________________________________________ - 05E5 1512 IDE_WAIT_DRQ_READY: - 05E5 DB 27 1513 IN A,(IDESTTS) ; READ ERROR REG - 05E7 E6 08 1514 AND #0b000001000 ; MASK OFF RDY BIT - 05E9 28 FA 1515 JR Z,IDE_WAIT_DRQ_READY ; WE WANT DRQ(3) TO BE 1 - 05EB C9 1516 RET - 1517 - 1518 ;___IDE_WAIT_DRQ_ZERO____________________________________________________________________________________ - 1519 ; - 1520 ; WAIT FOR IDE DRQ TO BE ZERO - 1521 ;________________________________________________________________________________________________________ - 05EC 1522 IDE_WAIT_DRQ_ZERO: - 05EC DB 27 1523 IN A,(IDESTTS) ; READ ERROR REG - 05EE E6 08 1524 AND #0b000001000 ; MASK OFF RDY BIT - 05F0 20 FA 1525 JR NZ,IDE_WAIT_DRQ_ZERO ; WE WANT DRQ(3) TO BE 0 - 05F2 C9 1526 RET - 1527 - 1528 ;___IDE_WAIT_BUSY_READY___________________________________________________________________________________ - 1529 ; - 1530 ; WAIT FOR IDE CHANNEL TO BE READY - 1531 ;________________________________________________________________________________________________________ - 05F3 1532 IDE_WAIT_BUSY_READY: - 05F3 11 00 00 1533 LD DE,#0 ; CLEAR DE - 05F6 1534 IDE_WBSY: ; - 05F6 06 05 1535 LD B,#5 ; SETUP TIMEOUT - 05F8 1536 IDE_DLP: ; - 05F8 05 1537 DEC B ; - 05F9 C2rF8s05 1538 JP NZ,IDE_DLP ; - 05FC 13 1539 INC DE ; - 05FD 7A 1540 LD A,D ; - 05FE B3 1541 OR E ; - 05FF CAr0Ds06 1542 JP Z,IDE_TO ; - 0602 DB 27 1543 IN A,(IDESTTS) ; READ ERROR REG - 0604 E6 C0 1544 AND #0b011000000 ; MASK OFF BUSY AND RDY BITS - 0606 EE 40 1545 XOR #0b001000000 ; WE WANT BUSY(7) TO BE 0 AND RDY(6) TO BE 1 - 0608 C2rF6s05 1546 JP NZ,IDE_WBSY ; - 060B 37 1547 SCF ; CARRY 1 = OK - 060C C9 1548 RET - 060D 1549 IDE_TO: - 060D AF 1550 XOR A ; CARRY 0 = TIMED OUT - 060E C9 1551 RET - 1552 - 1553 ;___IDE_TEST_ERROR_______________________________________________________________________________________ - 1554 ; - 1555 ; CHECK FOR IDE ERROR CONDITION - 1556 ;________________________________________________________________________________________________________ - 060F 1557 IDE_TEST_ERROR: - 060F 37 1558 SCF ; - 0610 DB 27 1559 IN A,(IDESTTS) ; - 0612 47 1560 LD B,A ; - 0613 E6 01 1561 AND #0b000000001 ; TEST ERROR BIT - 0615 37 1562 SCF ; - 0616 C8 1563 RET Z ; - 0617 78 1564 LD A,B ; - 0618 E6 20 1565 AND #0b000100000 ; - 061A 37 1566 SCF ; - 061B C2r20s06 1567 JP NZ,IDE_ERR ; TEST WRITE ERROR BIT - 061E DB 21 1568 IN A,(IDEERR) ; READ ERROR FLAGS - 0620 1569 IDE_ERR: - 0620 B7 1570 OR A ; CARRY 0 = ERROR - 0621 C9 1571 RET ; IF A = 0, IDE BUSY TIMED OUT - 1572 - 1573 ;___IDE_WAIT_BUFFER_______________________________________________________________________________________ - 1574 ; - 1575 ; WAIT FOR DATA BUFFER READY - 1576 ;________________________________________________________________________________________________________ - 0622 1577 IDE_WAIT_BUFFER: - 0622 11 00 00 1578 LD DE,#0 ; - 0625 1579 IDE_WDRQ: ; - 0625 06 05 1580 LD B,#5 ; - 0627 1581 IDE_BLP: ; - 0627 05 1582 DEC B ; - 0628 C2r27s06 1583 JP NZ,IDE_BLP ; - 062B 13 1584 INC DE ; - 062C 7A 1585 LD A,D ; - 062D B3 1586 OR E ; - 062E CAr3As06 1587 JP Z,IDE_TO2 ; - 0631 DB 27 1588 IN A,(IDESTTS) ; WAIT FOR DRIVE'S 512 BYTE READ BUFFER - 0633 E6 08 1589 AND #0b000001000 ; TO FILL (OR READY TO FILL) - 0635 CAr25s06 1590 JP Z,IDE_WDRQ ; - 0638 37 1591 SCF ; CARRY 1 = OK - 0639 C9 1592 RET ; - 063A 1593 IDE_TO2: ; - 063A AF 1594 XOR A ; CARRY 0 = TIMED OUT - 063B C9 1595 RET ; - 1596 - 1597 ;___IDE_READ_BUFFER_______________________________________________________________________________________ - 1598 ; - 1599 ; READ IDE BUFFER - 1600 ;________________________________________________________________________________________________________ - 063C 1601 IDE_READ_BUFFER: - 063C E5 1602 PUSH HL ; - 063D 21rE2s0F 1603 LD HL,#SECTOR_BUFFER ; - 0640 06 00 1604 LD B,#0 ; 256 WORDS (512 BYTES PER SECTOR) - 0642 1605 IDEBUFRD: ; - 0642 DB 20 1606 IN A,(IDELO) ; LOW BYTE OF WORD FIRST - 0644 77 1607 LD (HL),A ; - 0645 DB 28 1608 IN A,(IDEHI) ; THEN HIGH BYTE OF WORD - 0647 23 1609 INC HL ; - 0648 77 1610 LD (HL),A ; - 0649 23 1611 INC HL ; - 064A 05 1612 DEC B ; - 064B C2r42s06 1613 JP NZ,IDEBUFRD ; - 064E E1 1614 POP HL ; - 064F C9 1615 RET - 1616 - 1617 ;___IDE_WRITE_BUFFER_______________________________________________________________________________________ - 1618 ; - 1619 ; WRITE TO IDE BUFFER - 1620 ;________________________________________________________________________________________________________ - 0650 1621 IDE_WRITE_BUFFER: - 0650 E5 1622 PUSH HL ; - 0651 21rE2s0F 1623 LD HL,#SECTOR_BUFFER ; - 0654 06 00 1624 LD B,#0 ; 256 WORDS (512 BYTES PER SECTOR) - 0656 1625 IDEBUFWT: - 0656 23 1626 INC HL ; - 0657 7E 1627 LD A,(HL) ; - 0658 2B 1628 DEC HL ; - 0659 D3 28 1629 OUT (IDEHI),A ; SET UP HIGH LATCHED BYTE BEFORE - 065B 7E 1630 LD A,(HL) ; - 065C D3 20 1631 OUT (IDELO),A ; WRITING WORD WITH WRITE TO LOW BYTE - 065E 23 1632 INC HL ; - 065F 23 1633 INC HL ; - 0660 05 1634 DEC B ; - 0661 C2r56s06 1635 JP NZ,IDEBUFWT ; - 0664 E1 1636 POP HL ; - 0665 C9 1637 RET - 1638 - 1639 ;___IDE_SETUP_LDA________________________________________________________________________________________ - 1640 ; - 1641 ; SETUP IDE DRIVE FOR LDA OPERATION - 1642 ;________________________________________________________________________________________________________ - 0666 1643 IDE_SETUP_LBA: - 0666 3Ar13s0B 1644 LD A,(LBA_TARGET_LO) ; LOAD LBA REGISTER 0 WITH SECTOR ADDRESS TO READ - 0669 32r18s0B 1645 LD (IDE_LBA0),A ; - 066C 3Ar14s0B 1646 LD A,(LBA_TARGET_LO+1) ; LOAD LBA REGISTER 1 WITH SECTOR ADDRESS TO READ - 066F 32r19s0B 1647 LD (IDE_LBA1),A ; - 0672 3Ar15s0B 1648 LD A,(LBA_TARGET_HI) ; LOAD LBA REGISTER 2 WITH SECTOR ADDRESS TO READ - 0675 32r1As0B 1649 LD (IDE_LBA2),A ; - 0678 3Ar16s0B 1650 LD A,(LBA_TARGET_HI+1) ; LOAD LBA REGISTER 3 WITH SECTOR ADDRESS TO READ - 067B E6 0F 1651 AND #0b000001111 ; ONLY LOWER FOUR BITS ARE VALID - 067D C6 E0 1652 ADD A,#0b011100000 ; ENABLE LBA BITS 5:7=111 IN IDE_LBA3 - 067F 32r1Bs0B 1653 LD (IDE_LBA3),A ; - 1654 ; READ IDE HD SECTOR - 0682 3E 01 1655 LD A,#1 ; - 0684 D3 22 1656 OUT (IDESECTC),A ; SET SECTOR COUNT = 1 - 1657 ; - 0686 3Ar18s0B 1658 LD A,(IDE_LBA0) ; - 0689 D3 23 1659 OUT (IDESECTN),A ; SET LBA 0:7 - 1660 ; - 068B 3Ar19s0B 1661 LD A,(IDE_LBA1) ; - 068E D3 24 1662 OUT (IDECYLLO),A ; SET LBA 8:15 - 1663 ; - 0690 3Ar1As0B 1664 LD A,(IDE_LBA2) ; - 0693 D3 25 1665 OUT (IDECYLHI),A ; SET LBA 16:23 - 1666 ; - 0695 3Ar1Bs0B 1667 LD A,(IDE_LBA3) ; - 0698 E6 0F 1668 AND #0b000001111 ; LOWEST 4 BITS USED ONLY - 069A F6 E0 1669 OR #0b011100000 ; TO ENABLE LBA MODE - 069C D3 26 1670 OUT (IDEHEAD),A ; SET LBA 24:27 + BITS 5:7=111 - 0000 1671 .IF CONDUSEDSKY - 1672 CALL IDESEGDISPLAY ; - 1673 .ENDIF - 069E C9 1674 RET - 1675 - 1676 ;___ATAPI_SOFT_RESET_____________________________________________________________________________________ - 1677 ; - 1678 ; RESET ATAPI BUS - 1679 ;________________________________________________________________________________________________________ - 069F 1680 ATAPI_SOFT_RESET: - 069F 3E 0E 1681 LD A,#0b000001110 ;NO INTERRUPTS, RESET DRIVE = 1 - 06A1 D3 2E 1682 OUT (IDECTRL),A ; - 06A3 CDrD7s09 1683 CALL DELAY24 ; - 06A6 3E 0A 1684 LD A,#0b000001010 ;NO INTERRUPTS, RESET DRIVE = 0 - 06A8 D3 2E 1685 OUT (IDECTRL),A ; - 06AA CDrCFs05 1686 CALL ATAPI_WAIT_BUSY_READY ; - 06AD D0 1687 RET NC ; ERROR, RETURN - 06AE CDrD7s06 1688 CALL ATAPI_DEVICE_SELECTION ; - 06B1 CDrD7s09 1689 CALL DELAY24 ; - 06B4 CDrB8s06 1690 CALL REQUEST_SENSE_LOOP ; - 06B7 C9 1691 RET - 1692 - 1693 ;___REQUEST_SENSE_LOOP____________________________________________________________________________________ - 1694 ; - 1695 ; ATAPI_REQUEST SENSE DATA - 1696 ;_________________________________________________________________________________________________________ - 06B8 1697 REQUEST_SENSE_LOOP: - 06B8 21r80s0A 1698 LD HL,#ATAPI_REQUEST_SENSE ; - 06BB CDr7Ds07 1699 CALL ATAPI_SEND_PACKET ; - 06BE CDrCFs05 1700 CALL ATAPI_WAIT_BUSY_READY ; MAKE SURE DRIVE IS READY TO PROCEED - 06C1 D0 1701 RET NC ; ERROR, RETURN - 06C2 06 00 1702 LD B,#0 ; 256 WORDS (512 BYTES PER SECTOR) - 06C4 1703 REQUEST_SENSE_LOOP1: ; - 06C4 DB 20 1704 IN A,(IDELO) ; - 06C6 DD 23 1705 INC IX ; - 06C8 DB 28 1706 IN A,(IDEHI) ; - 06CA DD 23 1707 INC IX ; - 06CC 10 F6 1708 DJNZ REQUEST_SENSE_LOOP1 ; - 06CE ED 67 1709 RRD ; DELAY ONLY - 06D0 DB 27 1710 IN A,(IDESTTS) ;READ ERROR REG - 06D2 E6 01 1711 AND #0b000000001 ;MASK OFF BIT - 06D4 20 E2 1712 JR NZ,REQUEST_SENSE_LOOP ; - 06D6 C9 1713 RET - 1714 - 1715 ;___ATAPI_DEVICE_SELECTION________________________________________________________________________________ - 1716 ; - 1717 ; ATAPI DEVICE SELECTION - 1718 ;_________________________________________________________________________________________________________ - 06D7 1719 ATAPI_DEVICE_SELECTION: - 1720 - 06D7 3Ar17s0B 1721 LD A,(IDEDEVICE) ; SELECTS DEVICE - 06DA F6 A0 1722 OR #0x0A0 ; - 06DC D3 26 1723 OUT (IDEHEAD),A ; - 06DE C9 1724 RET ; - 1725 - 1726 - 1727 - 1728 ;__ATAPI_READ_SECTOR_____________________________________________________________________________________________________________ - 1729 ; READ ATAPI SECTOR - 1730 ; - 1731 ; D E H L = SECTOR (DOUBLE WORD) TO READ - 1732 ;________________________________________________________________________________________________________________________________ - 06DF 1733 ATAPI_READ_SECTOR: - 06DF CDrDCs02 1734 CALL ISCUR ; - 06E2 CAr28s07 1735 JP Z,ATAPI_READ_DATA_EXIT ; - 06E5 3Ar13s0B 1736 LD A,(LBA_TARGET_LO) ; LOAD LBA REGISTER 0 WITH SECTOR ADDRESS TO READ - 06E8 32r6Ds0A 1737 LD (READ_DISK_PACKET+5),A ; - 06EB 3Ar14s0B 1738 LD A,(LBA_TARGET_LO+1) ; LOAD LBA REGISTER 1 WITH SECTOR ADDRESS TO READ - 06EE 32r6Cs0A 1739 LD (READ_DISK_PACKET+4),A ; - 06F1 3Ar15s0B 1740 LD A,(LBA_TARGET_HI) ; LOAD LBA REGISTER 2 WITH SECTOR ADDRESS TO READ - 06F4 32r6Bs0A 1741 LD (READ_DISK_PACKET+3),A ; - 06F7 3Ar16s0B 1742 LD A,(LBA_TARGET_HI+1) ; LOAD LBA REGISTER 3 WITH SECTOR ADDRESS TO READ - 06FA 32r6As0A 1743 LD (READ_DISK_PACKET+2),A ; - 0000 1744 .IF CONDUSEDSKY - 1745 CALL ATAPISEGDISPLAY ; - 1746 .ENDIF - 06FD CDrB8s06 1747 CALL REQUEST_SENSE_LOOP ; GET ATAPI SENSE CODES TO CLEAR ERRORS - 0700 21r68s0A 1748 LD HL,#READ_DISK_PACKET ; SET POINTER TO READ SECTOR PACKET - 0703 CDr7Ds07 1749 CALL ATAPI_SEND_PACKET ; SEND PACKET COMMAND - 0706 CDrCFs05 1750 CALL ATAPI_WAIT_BUSY_READY ; MAKE SURE DRIVE IS READY TO PROCEED - 0709 D0 1751 RET NC ; ERROR, RETURN - 070A 06 00 1752 LD B,#0 ; 256 WORDS (512 BYTES PER SECTOR) - 070C DD 21rE2s0F 1753 LD IX,#SECTOR_BUFFER ; - 0710 DB 27 1754 IN A,(IDESTTS) ; READ REG - 0712 E6 08 1755 AND #0b000001000 ; MASK OFF BIT - 0714 FE 08 1756 CP #8 ; IS DATA WAITING? - 0716 20 10 1757 JR NZ,ATAPI_READ_DATA_EXIT ; NO, EXIT - 0718 1758 ATAPI_READ_DATA_LOOP: - 0718 DB 20 1759 IN A,(IDELO) ; - 1760 - 071A DD 77 00 1761 LD (IX),A ; - 1762 - 071D DD 23 1763 INC IX ; - 071F DB 28 1764 IN A,(IDEHI) ; - 1765 - 0721 DD 77 00 1766 LD (IX),A ; - 1767 - 0724 DD 23 1768 INC IX ; - 0726 10 F0 1769 DJNZ ATAPI_READ_DATA_LOOP ; - 0728 1770 ATAPI_READ_DATA_EXIT: ; - 0728 2Ar0Cs0B 1771 LD HL,(PSECTOR) ; STORE PHYSICAL SECTOR IN BUFFER - 072B 22rDEs0F 1772 LD (CUSECTOR),HL ; - 072E 2Ar04s0B 1773 LD HL,(PTRACK) ; STORE PHYSICAL DISK TRACK IN BUFFER - 0731 22rE0s0F 1774 LD (CUTRACK),HL ; - 0734 3Ar12s0B 1775 LD A,(DISKNO) ; STORE CURRENT DRIVE IN BUFFER - 0737 32rDDs0F 1776 LD (CUDISK),A ; - 073A 37 1777 SCF ; CARRY = 1 ON RETURN = OPERATION OK - 073B C9 1778 RET ; - 1779 - 1780 - 1781 - 1782 ;__ATAPI_WRITE_SECTOR_____________________________________________________________________________________________________________ - 1783 ; WRITE ATAPI SECTOR - 1784 ; - 1785 ; D E H L = SECTOR (DOUBLE WORD) TO WRITE - 1786 ;________________________________________________________________________________________________________________________________ - 073C 1787 ATAPI_WRITE_SECTOR: - 1788 - 073C 3Ar13s0B 1789 LD A,(LBA_TARGET_LO) ; LOAD LBA REGISTER 0 WITH SECTOR ADDRESS TO READ - 073F 32r79s0A 1790 LD (WRITE_DISK_PACKET+5),A ; - 0742 3Ar14s0B 1791 LD A,(LBA_TARGET_LO+1) ; LOAD LBA REGISTER 1 WITH SECTOR ADDRESS TO READ - 0745 32r78s0A 1792 LD (WRITE_DISK_PACKET+4),A ; - 0748 3Ar15s0B 1793 LD A,(LBA_TARGET_HI) ; LOAD LBA REGISTER 2 WITH SECTOR ADDRESS TO READ - 074B 32r77s0A 1794 LD (WRITE_DISK_PACKET+3),A ; - 074E 3Ar16s0B 1795 LD A,(LBA_TARGET_HI+1) ; LOAD LBA REGISTER 3 WITH SECTOR ADDRESS TO READ - 0751 32r76s0A 1796 LD (WRITE_DISK_PACKET+2),A ; - 0000 1797 .IF CONDUSEDSKY - 1798 CALL ATAPISEGDISPLAY ; - 1799 .ENDIF - 0754 CDrB8s06 1800 CALL REQUEST_SENSE_LOOP ; - 0757 21r74s0A 1801 LD HL,#WRITE_DISK_PACKET ; SET POINTER TO WRITE PACKET COMMAND - 075A CDr7Ds07 1802 CALL ATAPI_SEND_PACKET ; SEND THE PACKET COMMAND - 075D CDrCFs05 1803 CALL ATAPI_WAIT_BUSY_READY ; MAKE SURE DRIVE IS READY TO PROCEED - 0760 D0 1804 RET NC ; ERROR, RETURN - 0761 06 00 1805 LD B,#0 ; 256 WORDS (512 BYTES PER SECTOR) - 0763 DD 21rE2s0F 1806 LD IX,#SECTOR_BUFFER ; - 0767 1807 ATAPI_WRITE_DATA_LOOP: - 0767 DB 27 1808 IN A,(IDESTTS) ; READ REG - 1809 - 0769 DD 7E 00 1810 LD A,(IX) ; - 1811 - 076C F5 1812 PUSH AF ; - 076D DD 23 1813 INC IX ; - 1814 - 076F DD 7E 00 1815 LD A,(IX) ; - 1816 - 0772 D3 28 1817 OUT (IDEHI),A ; - 0774 F1 1818 POP AF ; - 0775 D3 20 1819 OUT (IDELO),A ; - 0777 DD 23 1820 INC IX ; - 0779 10 EC 1821 DJNZ ATAPI_WRITE_DATA_LOOP ; - 077B 37 1822 SCF ; CARRY = 1 ON RETURN = OPERATION OK - 077C C9 1823 RET ; - 1824 - 1825 - 1826 - 1827 - 1828 ;__ATAPI_SEND_PACKET_____________________________________________________________________________________________________________ - 1829 ; SEND PACKET POINTED TO BY HL TO ATAPI DRIVE - 1830 ; - 1831 ;________________________________________________________________________________________________________________________________ - 077D 1832 ATAPI_SEND_PACKET: - 1833 - 077D CDrCFs05 1834 CALL ATAPI_WAIT_BUSY_READY ; MAKE SURE DRIVE IS READY TO PROCEED - 0780 D0 1835 RET NC ; ERROR, RETURN - 0781 CDrECs05 1836 CALL IDE_WAIT_DRQ_ZERO ; - 1837 ; - 0784 3E 0A 1838 LD A,#0x0A ; - 0786 D3 2E 1839 OUT (IDECTRL),A ; DISABLE INT - 0788 3E 00 1840 LD A,#0 ; - 078A D3 21 1841 OUT (IDEERR),A ; - 078C 3E 00 1842 LD A,#0 ; - 078E D3 22 1843 OUT (IDESECTC),A ; - 0790 3E 00 1844 LD A,#0 ; - 0792 D3 23 1845 OUT (IDESECTN),A ; - 0794 3E 00 1846 LD A,#0 ; - 0796 D3 24 1847 OUT (IDECYLLO),A ; - 0798 3E 60 1848 LD A,#0x60 ; - 079A D3 25 1849 OUT (IDECYLHI),A ; - 079C 3Ar17s0B 1850 LD A,(IDEDEVICE) ; - 079F D3 26 1851 OUT (IDEHEAD),A ; BIT 4 SELECTS DEVICE - 07A1 3E A0 1852 LD A,#0x0A0 ; - 07A3 D3 27 1853 OUT (IDESTTS),A ; - 1854 ; - 07A5 CDrE5s05 1855 CALL IDE_WAIT_DRQ_READY ; MAKE SURE DRIVE IS READY TO PROCEED - 1856 ; - 07A8 06 06 1857 LD B,#6 ; SEND 12 BYTES (6 WORDS) - 1858 ; - 07AA 1859 ATAPI_SEND_PACKET_LOOP: - 07AA 7E 1860 LD A,(HL) ; GET BYTE - 07AB 57 1861 LD D,A ; STORE LOW BYTE IN D - 07AC 23 1862 INC HL ; INC POINTER - 07AD 7E 1863 LD A,(HL) ; GET HIGH BYTE - 07AE D3 28 1864 OUT (IDEHI),A ; STORE HIGH BYTE - 07B0 7A 1865 LD A,D ; MOVE LOW BYTE INTO A - 07B1 D3 20 1866 OUT (IDELO),A ; STORE LOW BYTE - 07B3 23 1867 INC HL ; INC POINTER - 07B4 DB 2E 1868 IN A,(IDECTRL) ; GET STATUS - 07B6 10 F2 1869 DJNZ ATAPI_SEND_PACKET_LOOP ; LOOP - 1870 ; - 07B8 CDrCFs05 1871 CALL ATAPI_WAIT_BUSY_READY ; MAKE SURE DRIVE IS READY TO PROCEED - 07BB D0 1872 RET NC ; ERROR, RETURN - 07BC DB 2E 1873 IN A,(IDECTRL) ; READ STATUS (FOR DELAY) - 1874 ; - 07BE C9 1875 RET ; - 1876 - 1877 ;__SETUPDRIVE__________________________________________________________________________________________________________________________ - 1878 ; - 1879 ; SETUP FLOPPY DRIVE SETTINGS - 1880 ;________________________________________________________________________________________________________________________________ - 1881 ; - 07BF 1882 SETUPDRIVE: - 07BF 3E 02 1883 LD A,#RESETL ; RESET SETTINGS - 0000 1884 .IF COND144FLOPPY-1 - 1885 OR MINI ; SELECT MINI FLOPPY (LOW DENS=1, HIGH DENS=0) - 1886 .ENDIF - 07C1 F6 20 1887 OR #PRECOMP ; SELECT PRECOMP - 07C3 F6 40 1888 OR #FDDENSITY ; SELECT DENSITY - 07C5 F6 80 1889 OR #FDREADY ; SELECT READY SIGNAL - 07C7 32r01s0B 1890 LD (FLATCH_STORE),A ; SAVE SETTINGS - 07CA 3E 01 1891 LD A,#1 ; - 07CC 32rEAs0A 1892 LD (UNIT),A ; SET UNIT 1 - 07CF 3E 02 1893 LD A,#2 ; DENSITY - 07D1 32rECs0A 1894 LD (DENS),A ; - 07D4 3E 09 1895 LD A,#9 ; - 0001 1896 .IF COND144FLOPPY - 07D6 87 1897 ADD A,A - 1898 .ENDIF - 07D7 32rEDs0A 1899 LD (EOTSEC),A ; LAST SECTOR OF TRACK - 07DA 3E 7F 1900 LD A,#0x7F ; - 07DC 32rF2s0A 1901 LD (SRTHUT),A ; STEP RATE AND HEAD UNLOAD TIME - 07DF 3E 05 1902 LD A,#5 ; - 07E1 32rF3s0A 1903 LD (HLT),A ; HEAD LOAD TIME - 07E4 3E 0D 1904 LD A,#0x0D ; - 07E6 32rEEs0A 1905 LD (GAP),A ; GAP - 1906 ;; LD A,#0x80 ; - 1907 ;; LD (SECSIZ),A ; SECTOR SIZE /4 - 1908 ; - 07E9 CDrE4s09 1909 CALL CHECKINT ; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR - 07EC CDrE4s09 1910 CALL CHECKINT ; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR - 07EF CDrE4s09 1911 CALL CHECKINT ; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR - 07F2 CDrE4s09 1912 CALL CHECKINT ; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR - 07F5 CDrE4s09 1913 CALL CHECKINT ; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR - 07F8 CDrE4s09 1914 CALL CHECKINT ; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR - 1915 ; - 07FB 21r01s0B 1916 LD HL,#FLATCH_STORE ; POINT TO FLATCH - 07FE CB 8E 1917 RES 1,(HL) ; SET MOTOR ON - 0800 CDr18s08 1918 CALL OUTFLATCH ; OUTPUT TO CONTROLLER - 0803 00 1919 NOP ; - 0804 00 1920 NOP ; - 0805 3E 00 1921 LD A,#0 ; ZERO TRACK - 0807 32r04s0B 1922 LD (PTRACK),A ; STORE TRACK - 080A CDr24s09 1923 CALL SETTRACK ; DO IT - 080D 00 1924 NOP ; - 080E 00 1925 NOP ; - 080F 21r01s0B 1926 LD HL,#FLATCH_STORE ; POINT TO FLATCH - 0812 CB CE 1927 SET 1,(HL) ; SET MOTOR OFF - 0814 CDr18s08 1928 CALL OUTFLATCH ; OUTPUT TO CONTROLLER - 0817 C9 1929 RET - 1930 ; - 1931 ;__OUTFLATCH__________________________________________________________________________________________________________________________ - 1932 ; - 1933 ; SEND SETTINGS TO FLOPPY CONTROLLER - 1934 ;________________________________________________________________________________________________________________________________ - 1935 ; - 0818 1936 OUTFLATCH: - 0818 3Ar01s0B 1937 LD A,(FLATCH_STORE) ; SET A TO SETTINGS - 081B D3 3A 1938 OUT (FLATCH),A ; OUTPUT TO CONTROLLER - 081D C9 1939 RET - 1940 - 1941 ;__FLOPPYREAD__________________________________________________________________________________________________________________________ - 1942 ; - 1943 ; READ A FLOPPY DISK SECTOR - 1944 ;________________________________________________________________________________________________________________________________ - 1945 ; - 081E 1946 FLOPPYREAD: - 0000 1947 .IF CONDUSEDSKY - 1948 CALL SEGDISPLAY ; - 1949 .ENDIF - 081E 3E 46 1950 LD A,#0x46 ; BIT 6 SETS MFM, 06H IS READ COMMAND - 0820 32rE9s0A 1951 LD (CMD),A ; - 0823 C3r2Es08 1952 JP DSKOP ; - 1953 ; - 1954 ;__FLOPPYWRITE__________________________________________________________________________________________________________________________ - 1955 ; - 1956 ; WRITE A FLOPPY DISK SECTOR - 1957 ;________________________________________________________________________________________________________________________________ - 1958 ; - 0826 1959 FLOPPYWRITE: - 0000 1960 .IF CONDUSEDSKY - 1961 CALL SEGDISPLAY ; - 1962 .ENDIF - 0826 3E 45 1963 LD A,#0x45 ; BIT 6 SETS MFM, 05H IS WRITE COMMAND - 0828 32rE9s0A 1964 LD (CMD),A ; - 082B C3r2Es08 1965 JP DSKOP ; - 1966 ; - 1967 ;__DSKOP__________________________________________________________________________________________________________________________ - 1968 ; - 1969 ; PERFORM A DISK OPERATION - 1970 ;________________________________________________________________________________________________________________________________ - 1971 ; - 082E 1972 DSKOP: - 082E 21r01s0B 1973 LD HL,#FLATCH_STORE ; POINT TO FLATCH - 0831 CB CE 1974 SET 1,(HL) ; SET MOTOR OFF - 0833 CDr18s08 1975 CALL OUTFLATCH ; OUTPUT TO CONTROLLER - 1976 ; - 0836 CDrE4s09 1977 CALL CHECKINT ; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR - 0839 FE FF 1978 CP #0x0FF ; DID IT RETURN WITH ERROR CODE? - 083B CAr75s08 1979 JP Z,DSKEXIT ; IF YES, EXIT WITH ERROR CODE - 1980 ; - 083E 3ArEAs0A 1981 LD A,(UNIT) ; GET DISK UNIT NUMBER - 0841 E6 03 1982 AND #3 ; MASK FOR FOUR DRIVES - 0843 47 1983 LD B,A ; PARK IT IN B - 0844 3ArEBs0A 1984 LD A,(HEAD) ; GET HEAD SELECTION - 0847 E6 01 1985 AND #1 ; INSURE SINGLE BIT - 0849 17 1986 RLA ; - 084A 17 1987 RLA ; MOVE HEAD TO BIT 2 POSITION - 084B B0 1988 OR B ; OR HEAD TO UNIT BYTE IN COMMAND BLOCK - 084C 32rEAs0A 1989 LD (UNIT),A ; STORE IN UNIT - 1990 ; - 084F 21r01s0B 1991 LD HL,#FLATCH_STORE ; POINT TO FLATCH - 0852 CB 8E 1992 RES 1,(HL) ; SET MOTOR ON - 0854 CDr18s08 1993 CALL OUTFLATCH ; OUTPUT TO CONTROLLER - 1994 ; - 0857 3E 03 1995 LD A,#3 ; SPECIFY COMMAND - 0859 CDrC2s09 1996 CALL PFDATA ; PUSH IT - 085C 3ArF2s0A 1997 LD A,(SRTHUT) ; STEP RATE AND HEAD UNLOAD TIME - 085F CDrC2s09 1998 CALL PFDATA ; PUSH THAT - 0862 3ArF3s0A 1999 LD A,(HLT) ; - 0865 CDrC2s09 2000 CALL PFDATA ; PUSH THAT - 2001 ; - 0868 CDr24s09 2002 CALL SETTRACK ; PERFORM SEEK TO TRACK - 2003 ; - 086B C2r75s08 2004 JP NZ,DSKEXIT ; IF ERROR, EXIT - 2005 ; - 086E 3ArE9s0A 2006 LD A,(CMD) ; WHAT COMMAND IS PENDING? - 0871 B7 2007 OR A ; SET FLAGS - 0872 C3rA4s08 2008 JP DOSO4 ; NO, MUST BE READ OR WRITE COMMAND - 0875 2009 DSKEXIT: - 0875 21r01s0B 2010 LD HL,#FLATCH_STORE ; POINT TO FLATCH - 0878 CB CE 2011 SET 1,(HL) ; SET MOTOR OFF - 087A CDr18s08 2012 CALL OUTFLATCH ; OUTPUT TO CONTROLLER - 2013 ; - 087D F6 FF 2014 OR #0x0FF ; SET -1 IF ERROR - 087F C9 2015 RET - 2016 - 0880 2017 RESULT: - 0880 0E 07 2018 LD C,#7 ; LOAD C WITH NUMBER OF STATUS BYTES - 0882 21rF6s0A 2019 LD HL,#ST0 ; POINT TO STATS STORAGE - 0885 2020 RS3: - 0885 CDr30s0A 2021 CALL GFDATA ; GET FIRST BYTE - 0888 77 2022 LD (HL),A ; SAVE IT - 0889 23 2023 INC HL ; POINTER++ - 088A 0D 2024 DEC C ; CC-1 - 088B C2r85s08 2025 JP NZ,RS3 ; LOOP TIL C0 - 088E 3ArF6s0A 2026 LD A,(ST0) ; LOAD STS0 - 0891 E6 F8 2027 AND #0x0F8 ; MASK OFF DRIVE # - 0893 47 2028 LD B,A ; PARK IT - 0894 3ArF7s0A 2029 LD A,(ST1) ; LOAD STS1 - 0897 B0 2030 OR B ; ACC OR B ->ACC IF 0 THEN SUCCESS - 2031 ; - 0898 2032 RSTEXIT: - 0898 CDrE4s09 2033 CALL CHECKINT ; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR - 089B 21r01s0B 2034 LD HL,#FLATCH_STORE ; POINT TO FLATCH - 089E CB CE 2035 SET 1,(HL) ; SET MOTOR OFF - 08A0 CDr18s08 2036 CALL OUTFLATCH ; OUTPUT TO CONTROLLER - 2037 ; - 0000 2038 .IF CONDUSEDSKY - 2039 CALL SEGDISPLAY ; - 2040 .ENDIF - 08A3 C9 2041 RET ; DONE RETURN TO CALLER - 2042 - 2043 - 08A4 2044 DOSO4: - 2045 ; - 0001 2046 .IF 1 ; - 0038 2047 INT_LOC = 0x038 ; IM 1 INTERRUPT CALLS GO HERE - 2048 ; SET UP FOR I/O AT INTERRUPT LEVEL - 08A4 11 38 00 2049 LD DE,#INT_LOC - 08A7 21r1Es09 2050 LD HL,#INT_RD - 08AA 01 03 00 2051 LD BC,#L_INT_RD - 08AD 3ArE9s0A 2052 LD A,(CMD) ; - 08B0 E6 01 2053 AND #0b000000001 ; WRITE IS 1 - 08B2 CArB6s08 2054 JP Z,IS_READ - 08B5 09 2055 ADD HL,BC - 08B6 2056 IS_READ: - 08B6 ED B0 2057 LDIR - 2058 .ENDIF - 2059 - 08B8 21rE2s0F 2060 LD HL,#SECTOR_BUFFER ; GET BUFFER ADDRESS TO HL - 2061 ;; LD A,(SECSIZ) ; XFERLEN - 2062 ;; LD C,A ; C WILL BE THE NUMBER OF TRANSACTIONS - 2063 ; DIVIDED BY 4 - 2064 - 08BB ED 5BrEFs0A 2065 ld de,(FSECSIZ) ; GET FULL SECTOR SIZE - 08BF 43 2066 LD B,E - 08C0 0E 37 2067 LD C,#FDATA ; GET DATA REGISTER I/O ADDRESS - 2068 - 08C2 3ArE9s0A 2069 LD A,(CMD) ; - 08C5 CDrC2s09 2070 CALL PFDATA ; PUSH COMMAND TO I8272 - 08C8 3ArEAs0A 2071 LD A,(UNIT) ; - 08CB CDrC2s09 2072 CALL PFDATA ; - 08CE 3Ar04s0B 2073 LD A,(PTRACK) ; - 08D1 CDrC2s09 2074 CALL PFDATA ; - 08D4 3ArEBs0A 2075 LD A,(HEAD) ; - 08D7 CDrC2s09 2076 CALL PFDATA ; - 08DA 3Ar0Cs0B 2077 LD A,(PSECTOR) ; - 08DD 3C 2078 INC A ; - 08DE CDrC2s09 2079 CALL PFDATA ; - 08E1 3ArECs0A 2080 LD A,(DENS) ; - 08E4 CDrC2s09 2081 CALL PFDATA ; WHAT DENSITY - 08E7 3ArEDs0A 2082 LD A,(EOTSEC) ; - 08EA CDrC2s09 2083 CALL PFDATA ; ASSUME SC (SECTOR COUNT) EOT - 08ED 3ArEEs0A 2084 LD A,(GAP) ; - 08F0 CDrC2s09 2085 CALL PFDATA ; WHAT GAP IS NEEDED - 08F3 3ArF1s0A 2086 LD A,(DTL) ; DTL, IS THE LAST COMMAND BYTE TO I8272 - 08F6 CDrAFs09 2087 CALL PFDATAS ; - 2088 ; - 2089 ; - 2090 ; PERFORM READ / WRITE - 2091 ; - 2092 - 2093 - 08F9 2094 RDD_POLL: - 2095 - 08F9 2096 FDC_RW_P0: - 08F9 FB 2097 EI - 08FA 76 2098 HALT - 08FB C2rF9s08 2099 JP NZ,FDC_RW_P0 ;10 COUNT THRU 256 BYTES - 08FE 2100 FDC_RW_P1: - 08FE FB 2101 EI - 08FF 76 2102 HALT - 0900 C2rFEs08 2103 JP NZ,FDC_RW_P1 ;10 COUNT THRU 256 BYTES - 2104 - 2105 - 2106 ; FALL THROUGH WITH INTERRUPTS DISABLED (NOT ENABLED IN INTERRUPT SERVICE) - 2107 - 2108 - 0903 2109 DSKOPEND: - 0903 21r01s0B 2110 LD HL,#FLATCH_STORE ; POINT TO FLATCH - 0906 CB C6 2111 SET 0,(HL) ; SET TC - 0908 CDr18s08 2112 CALL OUTFLATCH ; OUTPUT TO CONTROLLER - 090B 00 2113 NOP ; - 090C 00 2114 NOP ; 2 MICROSECOND DELAY - 090D CB 86 2115 RES 0,(HL) ; RESET TC - 090F CDr18s08 2116 CALL OUTFLATCH ; OUTPUT TO CONTROLLER - 0912 00 2117 NOP ; - 0913 00 2118 NOP ; 2 MICROSECOND DELAY - 0914 00 2119 NOP ; - 0915 00 2120 NOP ; 2 MICROSECOND DELAY - 0916 CB CE 2121 SET 1,(HL) ; TURN OFF MOTOR - 0918 CDr18s08 2122 CALL OUTFLATCH ; OUTPUT TO CONTROLLER - 091B C3r80s08 2123 JP RESULT ; GET STATUS BYTES - 2124 - 2125 - 2126 - 091E ED A2 2127 INT_RD: INI - 0920 C9 2128 RET - 0921 2129 IRTEMP: - 0003 2130 L_INT_RD = IRTEMP - INT_RD - 2131 - 0921 ED A3 2132 INT_WR: OUTI - 0923 C9 2133 RET - 0924 2134 IWTEMP: - 0003 2135 L_INT_WR = IWTEMP - INT_WR - 2136 - 2137 - 2138 - 2139 ;__SETTRACK__________________________________________________________________________________________________________________________ - 2140 ; - 2141 ; SEEK TO A TRACK ON GIVEN UNIT - 2142 ; A: TRACK # - 2143 ;________________________________________________________________________________________________________________________________ - 2144 ; - 0924 2145 SETTRACK: - 0924 3Ar06s0B 2146 LD A,(FTRACK) ; GET CURRENT HEAD TRACK - 0927 4F 2147 LD C,A - 0928 3Ar04s0B 2148 LD A,(PTRACK) ; GET TRACK - 092B B7 2149 OR A ; SET FLAGS - 092C CAr4As09 2150 JP Z,RECAL ; IF 0 PERFORM RECAL INSTEAD OF SEEK - 092F B9 2151 CP C ; - 0930 CAr5As09 2152 JP Z,WAINT ; ALREADY THERE, ABORT - 0933 32r06s0B 2153 LD (FTRACK),A ; STORE TRACK - 0936 3E 0F 2154 LD A,#0x0F ; SEEK COMMAND - 0938 CDrC2s09 2155 CALL PFDATA ; PUSH COMMAND - 093B 3ArEAs0A 2156 LD A,(UNIT) ; SAY WHICH UNIT - 093E CDrC2s09 2157 CALL PFDATA ; SEND THAT - 0941 3Ar04s0B 2158 LD A,(PTRACK) ; TO WHAT TRACK - 0944 CDrC2s09 2159 CALL PFDATA ; SEND THAT TOO - 0947 C3r5As09 2160 JP WAINT ; WAIT FOR INTERRUPT SAYING DONE - 094A 2161 RECAL: - 094A 3E 00 2162 LD A,#0 ; - 094C 32r06s0B 2163 LD (FTRACK),A ; STORE TRACK - 094F 3E 07 2164 LD A,#7 ; RECAL TO TRACK 0 - 0951 CDrC2s09 2165 CALL PFDATA ; SEND IT - 0954 3ArEAs0A 2166 LD A,(UNIT) ; WHICH UNIT - 0957 CDrC2s09 2167 CALL PFDATA ; SEND THAT TOO - 2168 ; - 095A 2169 WAINT: - 2170 ; - 095A CDrF6s09 2171 CALL DELAYHSEC ; DELAY TO LET HEADS SETTLE BEFORE READ - 2172 ; - 2173 ; WAIT HERE FOR INTERRPT SAYING DONE - 2174 ; LOOP TIL INTERRUPT - 095D CDrE4s09 2175 CALL CHECKINT ; CHECK INTERRUPT STATUS - 2176 ; - 0960 C9 2177 RET - 2178 - 2179 ;__CYCLEFLOPPY__________________________________________________________________________________________________________________________ - 2180 ; - 2181 ; SEEK TO TRACK 0, THEN BACK TO THE SELECTED TRACK - 2182 ; THIS CAN BE USED ON AN ERROR CONDITION TO VERIFY THAT HEAD IS ON SELECTED TRACK - 2183 ; - 2184 ;________________________________________________________________________________________________________________________________ - 2185 ; - 0961 2186 CYCLEFLOPPY: - 0961 F5 2187 PUSH AF ; STORE AF - 0962 E5 2188 PUSH HL ; STORE HL - 0963 CDrE4s09 2189 CALL CHECKINT ; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR - 0966 CDrE4s09 2190 CALL CHECKINT ; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR - 0969 CDrE4s09 2191 CALL CHECKINT ; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR - 096C CDrE4s09 2192 CALL CHECKINT ; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR - 096F CDrE4s09 2193 CALL CHECKINT ; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR - 0972 CDrE4s09 2194 CALL CHECKINT ; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR - 0975 21r01s0B 2195 LD HL,#FLATCH_STORE ; POINT TO FLATCH - 0978 CB 8E 2196 RES 1,(HL) ; SET MOTOR ON - 097A CDr18s08 2197 CALL OUTFLATCH ; OUTPUT TO CONTROLLER - 097D 00 2198 NOP ; - 097E 00 2199 NOP ; - 097F CDr4As09 2200 CALL RECAL ; - 0982 CDrF6s09 2201 CALL DELAYHSEC ; - 0985 CDrF6s09 2202 CALL DELAYHSEC ; - 0988 CDrF6s09 2203 CALL DELAYHSEC ; - 098B CDrF6s09 2204 CALL DELAYHSEC ; - 098E CDr4As09 2205 CALL RECAL ; - 0991 CDrF6s09 2206 CALL DELAYHSEC ; - 0994 CDrF6s09 2207 CALL DELAYHSEC ; - 0997 CDrF6s09 2208 CALL DELAYHSEC ; - 099A CDrF6s09 2209 CALL DELAYHSEC ; - 099D CDr24s09 2210 CALL SETTRACK ; - 09A0 CDrF6s09 2211 CALL DELAYHSEC ; - 09A3 CDrF6s09 2212 CALL DELAYHSEC ; - 09A6 CDrF6s09 2213 CALL DELAYHSEC ; - 09A9 CDrF6s09 2214 CALL DELAYHSEC ; - 09AC E1 2215 POP HL ; - 09AD F1 2216 POP AF ; RESTORE AF - 09AE C9 2217 RET - 2218 - 2219 ;__PFDATAS__________________________________________________________________________________________________________________________ - 2220 ; - 2221 ; WRITE A COMMAND OR PARAMETER SEQUENCE - 2222 ; - 2223 ; TRANSFERS ARE SYNCHONIZED BYT MSR D7 AND D6 - 2224 ; RQM DIO - 2225 ; 0 0 BUSY - 2226 ; 1 0 WRITE TO DATA REGISTER PERMITTED - 2227 ; 1 1 BYTE FOR READ BY HOST PENDING - 2228 ; 0 1 BUSY - 2229 ; - 2230 ;________________________________________________________________________________________________________________________________ - 2231 ; - 09AF 2232 PFDATAS: - 09AF F5 2233 PUSH AF ; STORE AF - 09B0 2234 PFDS1: - 09B0 DB 36 2235 IN A,(FMSR) ; READING OR WRITING IS KEYS TO D7 RQM - 09B2 E6 80 2236 AND #0x80 ; MASK OFF RQM BIT - 09B4 CArB0s09 2237 JP Z,PFDS1 ; WAIT FOR RQM TO BE TRUE - 09B7 DB 36 2238 IN A,(FMSR) ; READ STATUS - 09B9 E6 40 2239 AND #0x40 ; WAITING FOR INPUT? - 09BB C4r06s0A 2240 CALL NZ,ERRORT ; NO, SIGNAL ERROR - 09BE F1 2241 POP AF ; RESTORE AF - 09BF D3 37 2242 OUT (FDATA),A ; OUTPUT A TO CONTROLLER - 09C1 C9 2243 RET - 2244 - 2245 ;__PFDATA__________________________________________________________________________________________________________________________ - 2246 ; - 2247 ; WRITE A COMMAND OR PARAMETER SEQUENCE - 2248 ; - 2249 ; TRANSFERS ARE SYNCHONIZED BYT MSR D7 AND D6 - 2250 ; RQM DIO - 2251 ; 0 0 BUSY - 2252 ; 1 0 WRITE TO DATA REGISTER PERMITTED - 2253 ; 1 1 BYTE FOR READ BY HOST PENDING - 2254 ; 0 1 BUSY - 2255 ; - 2256 ;________________________________________________________________________________________________________________________________ - 2257 ; - 09C2 2258 PFDATA: - 09C2 F5 2259 PUSH AF ; STORE AF - 09C3 2260 PFD1: - 09C3 DB 36 2261 IN A,(FMSR) ; READING OR WRITING IS KEYS TO D7 RQM - 09C5 E6 80 2262 AND #0x80 ; MASK OFF RQM BIT - 09C7 CArC3s09 2263 JP Z,PFD1 ; WAIT FOR RQM TO BE TRUE - 09CA DB 36 2264 IN A,(FMSR) ; READ STATUS - 09CC E6 40 2265 AND #0x40 ; WAITING FOR INPUT? - 09CE C4r06s0A 2266 CALL NZ,ERRORT ; NO, SIGNAL ERROR - 09D1 F1 2267 POP AF ; RESTORE AF - 09D2 D3 37 2268 OUT (FDATA),A ; OUTPUT A TO CONTROLLER - 09D4 C3rD7s09 2269 JP DELAY24 ; DELAY 24US - 2270 - 2271 - 2272 - 2273 ;__DELAY24__________________________________________________________________________________________________________________________ - 2274 ; - 2275 ; DELAY 24US - 2276 ;________________________________________________________________________________________________________________________________ - 2277 ; - 09D7 2278 DELAY24: - 2279 ; JP= 10T - 09D7 DD E5 2280 PUSH IX ; 15T - 09D9 DD E1 2281 POP IX ; 14T - 09DB DD E5 2282 PUSH IX ; 15T - 09DD DD E1 2283 POP IX ; 14T - 09DF 2284 DELAY12: - 09DF DD E5 2285 PUSH IX ; 15T - 09E1 DD E1 2286 POP IX ; 14T - 09E3 C9 2287 RET ; 10T - 2288 - 2289 - 2290 ;__CHECKINT__________________________________________________________________________________________________________________________ - 2291 ; - 2292 ; CHECK FOR ACTIVE FDC INTERRUPTS BEFORE GIVING I8272 COMMANDS - 2293 ; POLL RQM FOR WHEN NOT BUSY AND THEN SEND FDC - 2294 ; SENSE INTERRUPT COMMAND IF IT RETURNS WITH NON ZERO - 2295 ; ERROR CODE, PASS BACK TO CALLING ROUTINE FOR HANDLING - 2296 ;________________________________________________________________________________________________________________________________ - 2297 ; - 09E4 2298 CHECKINT: - 09E4 DB 36 2299 IN A,(FMSR) ; READING OR WRITING IS KEYS TO D7 RQM - 09E6 E6 80 2300 AND #0x80 ; MASK OFF RQM BIT - 09E8 CArE4s09 2301 JP Z,CHECKINT ; WAIT FOR RQM TO BE TRUE WAIT UNTIL DONE - 09EB DB 36 2302 IN A,(FMSR) ; READ STATUS - 09ED E6 40 2303 AND #0x40 ; WAITING FOR INPUT? - 09EF C2rF5s09 2304 JP NZ,CHECKINTDONE ; NO, SIGNAL ERROR - 09F2 CDr12s0A 2305 CALL SENDINT ; SENSE INTERRUPT COMMAND - 09F5 2306 CHECKINTDONE: - 09F5 C9 2307 RET ; - 2308 - 2309 - 2310 ;__DELAYHSEC__________________________________________________________________________________________________________________________ - 2311 ; - 2312 ; DELAY FOR 1/2 SECOND - 2313 ;________________________________________________________________________________________________________________________________ - 2314 ; - 09F6 2315 DELAYHSEC: - 09F6 21 00 00 2316 LD HL,#0 ; 65536 - 09F9 2317 DELDM: - 09F9 00 2318 NOP ; (4 T) - 09FA 00 2319 NOP ; (4 T) - 09FB 00 2320 NOP ; (4 T) - 09FC 00 2321 NOP ; (4 T) - 09FD 2D 2322 DEC L ; (6 T) - 09FE C2rF9s09 2323 JP NZ,DELDM ; (10 T) 24 T 8 MICROSECONDS AT 4 MHZ - 0A01 25 2324 DEC H ; (6 T) - 0A02 C2rF9s09 2325 JP NZ,DELDM ; (10 T) (8 US * 256) * 256 524288 US 5 SECONDS - 0A05 C9 2326 RET - 2327 - 2328 ;__ERRORT__________________________________________________________________________________________________________________________ - 2329 ; - 2330 ; ERROR HANDLING - 2331 ;________________________________________________________________________________________________________________________________ - 2332 ; - 0A06 2333 ERRORT: - 0A06 DB 37 2334 IN A,(FDATA) ; CLEAR THE JUNK OUT OF DATA REGISTER - 0A08 DB 36 2335 IN A,(FMSR) ; CHECK WITH RQM - 0A0A E6 80 2336 AND #0x80 ; IF STILL NOT READY, READ OUT MORE JUNK - 0A0C CAr06s0A 2337 JP Z,ERRORT ; - 0A0F 3E FF 2338 LD A,#0x0FF ; RETURN ERROR CODE -1 - 2339 ; - 0A11 C9 2340 RET - 2341 - 2342 ;__SENDINT__________________________________________________________________________________________________________________________ - 2343 ; - 2344 ; SENSE INTERRUPT COMMAND - 2345 ;________________________________________________________________________________________________________________________________ - 2346 ; - 0A12 2347 SENDINT: - 0A12 3E 08 2348 LD A,#8 ; SENSE INTERRUPT COMMAND - 0A14 CDrC2s09 2349 CALL PFDATA ; SEND IT - 0A17 CDr30s0A 2350 CALL GFDATA ; GET RESULTS - 0A1A 32rFDs0A 2351 LD (ST0A),A ; STORE THAT - 0A1D E6 C0 2352 AND #0x0C0 ; MASK OFF INTERRUPT STATUS BITS - 0A1F FE 80 2353 CP #0x80 ; CHECK IF INVALID COMMAND - 0A21 CAr2Fs0A 2354 JP Z,ENDSENDINT ; YES, EXIT - 0A24 CDr30s0A 2355 CALL GFDATA ; GET ANOTHER (STATUS CODE 1) - 0A27 32rFEs0A 2356 LD (ST1A),A ; SAVE THAT - 0A2A 3ArFDs0A 2357 LD A,(ST0A) ; GET FIRST ONE - 0A2D E6 C0 2358 AND #0x0C0 ; MASK OFF ALL BUT INTERRUPT CODE 00 IS NORMAL - 0A2F 2359 ENDSENDINT: - 0A2F C9 2360 RET ; ANYTHING ELSE IS AN ERROR - 2361 - 2362 - 2363 ;__GFDATA__________________________________________________________________________________________________________________________ - 2364 ; - 2365 ; GET DATA FROM FLOPPY CONTROLLER - 2366 ; - 2367 ; TRANSFERS ARE SYNCHONIZED BYT MSR D7 AND D6 - 2368 ; RQM DIO - 2369 ; 0 0 BUSY - 2370 ; 1 0 WRITE TO DATA REGISTER PERMITTED - 2371 ; 1 1 BYTE FOR READ BY HOST PENDING - 2372 ; 0 1 BUSY - 2373 ; - 2374 ;________________________________________________________________________________________________________________________________ - 2375 ; - 0A30 2376 GFDATA: - 0A30 DB 36 2377 IN A,(FMSR) ; READ STATUS BYTE - 0A32 E6 80 2378 AND #0x80 ; MASK OFF RQM - 0A34 CAr30s0A 2379 JP Z,GFDATA ; LOOP WHILE BUSY - 0A37 DB 36 2380 IN A,(FMSR) ; READ STSTUS BUTE - 0A39 E6 40 2381 AND #0x40 ; MASK OFF DIO - 0A3B CCr06s0A 2382 CALL Z,ERRORT ; IF WRITE EXPECTED RUN ERRORRT - 0A3E DB 37 2383 IN A,(FDATA) ; READ DATA - 0A40 C3rD7s09 2384 JP DELAY24 ; DELAY 24US - 2385 - 2386 - 2387 - 0000 2388 .IF CONDUSEDSKY - 2389 ;__IDESEGDISPLAY________________________________________________________________________________________ - 2390 ; - 2391 ; DISPLAY CONTENTS OF IDE LOGICAL BLOCK ADDRESS ON DSKY - 2392 ;____________________________________________________________________________________________________ - 2393 IDESEGDISPLAY: - 2394 LD A, #0x82 ; - 2395 OUT (PIOCONT),A ; - 2396 ; - 2397 LD A,(IDE_LBA3) ; - 2398 AND #0x0F ; - 2399 LD (DISPLAYBUF+6),A ; - 2400 LD A,(IDE_LBA3) ; - 2401 AND #0x0F0 ; - 2402 SRL A ; - 2403 SRL A ; - 2404 SRL A ; - 2405 SRL A ; - 2406 LD (DISPLAYBUF+7),A ; - 2407 ; - 2408 LD A,(IDE_LBA2) ; - 2409 AND #0x0F ; - 2410 LD (DISPLAYBUF+4),A ; - 2411 LD A,(IDE_LBA2) ; - 2412 AND #0x0F0 ; - 2413 SRL A ; - 2414 SRL A ; - 2415 SRL A ; - 2416 SRL A ; - 2417 LD (DISPLAYBUF+5),A ; - 2418 ; - 2419 LD A,(IDE_LBA1) ; - 2420 AND #0x0F ; - 2421 LD (DISPLAYBUF+2),A ; - 2422 LD A,(IDE_LBA1) ; - 2423 AND #0x0F0 ; - 2424 SRL A ; - 2425 SRL A ; - 2426 SRL A ; - 2427 SRL A ; - 2428 LD (DISPLAYBUF+3),A ; - 2429 - 2430 LD A,(IDE_LBA0) ; - 2431 AND #0x0F ; - 2432 LD (DISPLAYBUF),A ; - 2433 LD A,(IDE_LBA0) ; - 2434 AND #0x0F0 ; - 2435 SRL A ; - 2436 SRL A ; - 2437 SRL A ; - 2438 SRL A ; - 2439 LD (DISPLAYBUF+1),A ; - 2440 JP SEGDISPLAY1 ; - 2441 - 2442 ;__ATAPISEGDISPLAY________________________________________________________________________________________ - 2443 ; - 2444 ; DISPLAY CONTENTS OF ATAPI LOGICAL BLOCK ADDRESS ON DSKY - 2445 ;____________________________________________________________________________________________________ - 2446 ATAPISEGDISPLAY: - 2447 LD A, #0x82 ; - 2448 OUT (PIOCONT),A ; - 2449 ; - 2450 LD A,(LBA_TARGET_HI+1) ; - 2451 AND #0x0F ; - 2452 LD (DISPLAYBUF+6),A ; - 2453 LD A,(LBA_TARGET_HI+1) ; - 2454 AND #0x0F0 ; - 2455 SRL A ; - 2456 SRL A ; - 2457 SRL A ; - 2458 SRL A ; - 2459 LD (DISPLAYBUF+7),A ; - 2460 ; - 2461 LD A,(LBA_TARGET_HI) ; - 2462 AND #0x0F ; - 2463 LD (DISPLAYBUF+4),A ; - 2464 LD A,(LBA_TARGET_HI) ; - 2465 AND #0x0F0 ; - 2466 SRL A ; - 2467 SRL A ; - 2468 SRL A ; - 2469 SRL A ; - 2470 LD (DISPLAYBUF+5),A ; - 2471 ; - 2472 LD A,(LBA_TARGET_LO+1) ; - 2473 AND #0x0F ; - 2474 LD (DISPLAYBUF+2),A ; - 2475 LD A,(LBA_TARGET_LO+1) ; - 2476 AND #0x0F0 ; - 2477 SRL A ; - 2478 SRL A ; - 2479 SRL A ; - 2480 SRL A ; - 2481 LD (DISPLAYBUF+3),A ; - 2482 ; - 2483 LD A,(LBA_TARGET_LO) ; - 2484 AND #0x0F ; - 2485 LD (DISPLAYBUF),A ; - 2486 LD A,(LBA_TARGET_LO) ; - 2487 AND #0x0F0 ; - 2488 SRL A ; - 2489 SRL A ; - 2490 SRL A ; - 2491 SRL A ; - 2492 LD (DISPLAYBUF+1),A ; - 2493 JP SEGDISPLAY1 ; - 2494 - 2495 ;__SEGDISPLAY________________________________________________________________________________________ - 2496 ; - 2497 ; DISPLAY CONTENTS OF TRACK, SECTOR, ST0, ST1 ON DSKY - 2498 ; - 2499 ;____________________________________________________________________________________________________ - 2500 SEGDISPLAY: - 2501 LD A, #0x82 ; - 2502 OUT (PIOCONT),A ; - 2503 LD A,(TRACK) ; - 2504 AND #0x0F ; - 2505 LD (DISPLAYBUF+6),A ; - 2506 LD A,(TRACK) ; - 2507 AND #0x0F0 ; - 2508 SRL A ; - 2509 SRL A ; - 2510 SRL A ; - 2511 SRL A ; - 2512 LD (DISPLAYBUF+7),A ; - 2513 LD A,(SECTOR) ; - 2514 AND #0x0F ; - 2515 LD (DISPLAYBUF+4),A ; - 2516 LD A,(SECTOR) ; - 2517 AND #0x0F0 ; - 2518 SRL A ; - 2519 SRL A ; - 2520 SRL A ; - 2521 SRL A ; - 2522 LD (DISPLAYBUF+5),A ; - 2523 LD A,(ST0) ; - 2524 AND #0x0F ; - 2525 LD (DISPLAYBUF+2),A ; - 2526 LD A,(ST0) ; - 2527 AND #0x0F0 ; - 2528 SRL A ; - 2529 SRL A ; - 2530 SRL A ; - 2531 SRL A ; - 2532 LD (DISPLAYBUF+3),A ; - 2533 LD A,(ST1) ; - 2534 AND #0x0F ; - 2535 LD (DISPLAYBUF),A ; - 2536 LD A,(ST1) ; - 2537 AND #0x0F0 ; - 2538 SRL A ; - 2539 SRL A ; - 2540 SRL A ; - 2541 SRL A ; - 2542 LD (DISPLAYBUF+1),A ; - 2543 SEGDISPLAY1: ; - 2544 LD HL,#DISPLAYBUF ; - 2545 LD BC,#7 ; - 2546 ADD HL,BC ; - 2547 LD B,#8 ; SET DIGIT COUNT - 2548 LD A,#0x40 ; SET CONTROL PORT 7218 TO OFF - 2549 OUT (PORTC),A ; OUTPUT - 2550 CALL DELAY12 ; WAIT - 2551 LD A,#0x0D0 ; SET CONTROL TO 1111 (DATA COMING, HEX DECODE, DECODE, NORMAL) - 2552 OUT (PORTA),A ; OUTPUT TO PORT - 2553 LD A,#0x80 ; STROBE WRITE PULSE WITH CONTROL=1 - 2554 OUT (PORTC),A ; OUTPUT TO PORT - 2555 CALL DELAY12 ; WAIT - 2556 LD A,#0x40 ; SET CONTROL PORT 7218 TO OFF - 2557 OUT (PORTC),A ; OUTPUT - 2558 CALL DELAY12 ; WAIT - 2559 SEGDISPLAY_LP: - 2560 LD A,(HL) ; GET DISPLAY DIGIT - 2561 OUT (PORTA),A ; OUT TO PORTA - 2562 LD A,#0 ; SET WRITE STROBE - 2563 OUT (PORTC),A ; OUT TO PORTC - 2564 CALL DELAY12 ; DELAY - 2565 LD A,#0x40 ; SET CONTROL PORT OFF - 2566 OUT (PORTC),A ; OUT TO PORTC - 2567 CALL DELAY12 ; WAIT - 2568 DEC HL ; INC POINTER - 2569 DJNZ SEGDISPLAY_LP ; LOOP FOR NEXT DIGIT - 2570 RET - 2571 - 2572 DISPLAYBUF: .DB 01,02,03,04,05,06,07,08 - 2573 .ENDIF - 0A43 00 00 00 00 00 00 2574 .DB 00,00,00,00,00,00,00,00 - 00 00 - 0A4B 00 00 00 00 00 00 2575 .DB 00,00,00,00,00,00,00,00 - 00 00 - 0A53 00 00 00 00 00 00 2576 .DB 00,00,00,00,00,00,00,00 - 00 00 - 0A5B 00 00 00 00 00 00 2577 .DB 00,00,00,00,00,00,00,00 - 00 00 - 2578 - 2579 - 2580 - 0A63 00 2581 FLOPPYSTACK: .DB 00 - 0A64 00 00 00 00 2582 PARKSTACK: .DB 00,00,00,00 - 2583 - 0A68 2584 READ_DISK_PACKET: - 0A68 A8 00 00 00 00 01 2585 .DB 0x0A8,00,00,00,00,01,00,00,00,01,00,00 - 00 00 00 01 00 00 - 0A74 2586 WRITE_DISK_PACKET: - 0A74 2A 00 00 00 00 11 2587 .DB 0x2A,00,00,00,00,0x11,00,00,01,00,00,00 - 00 00 01 00 00 00 - 0A80 2588 ATAPI_REQUEST_SENSE: - 0A80 03 00 00 00 11 00 2589 .DB 3,00,00,00,0x11,00,00,00,00,00,00,00 - 00 00 00 00 00 00 - 2590 - 2591 ; ******* TEXT STRINGS ******* - 2592 - 0A8C 2593 TXT_RO_ERROR: - 0A8C 0D 0A 2594 .DB CR,LF - 0A8E 45 52 52 4F 52 3A 2595 .ascii "ERROR: WRITE TO READ ONLY DISK" - 20 57 52 49 54 45 - 20 54 4F 20 52 45 - 41 44 20 4F 4E 4C - 59 20 44 49 53 4B - 0AAC FF 2596 .DB END - 2597 - 2598 - 0AAD 2599 TXT_STARTUP_MSG: - 2600 - 0001 2601 .IF CONDSHORTMSG - 0AAD 0D 0A 2602 .DB CR,LF - 0AAF 43 50 2F 4D 2D 38 2603 .ascii "CP/M-80 2.2C (JC0705-1) for " - 30 20 32 2E 32 43 - 20 28 4A 43 30 37 - 30 35 2D 31 29 20 - 66 6F 72 20 - 0ACB 4E 38 56 45 4D 20 2604 .ascii "N8VEM - W/" - 2D 20 57 2F - 0000 2605 .IF CONDUSEVDU - 2606 .ascii "VDU " - 2607 .ENDIF - 0000 2608 .IF CONDUSEDSKY - 2609 .ascii "DSKY " - 2610 .ENDIF - 0001 2611 .IF CONDIDESOFT - 0AD5 49 44 45 20 2612 .ascii "IDE " - 2613 .ENDIF - 0000 2614 .IF CONDUSEATAPI - 2615 .ascii "ATAPI " - 2616 .ENDIF - 0001 2617 .IF CONDUSEFLOPPY - 0AD9 46 4C 4F 50 50 59 2618 .ascii "FLOPPY " - 20 - 0001 2619 .IF COND144FLOPPY - 0AE0 31 2E 34 34 4D 20 2620 .ascii "1.44M " - 2621 .ENDIF - 2622 .ENDIF - 0AE6 0D 0A 2623 .DB CR,LF - 0AE8 FF 2624 .DB END - 2625 .ELSE - 2626 .ascii "CP/M V2.2C" - 2627 .DB END - 2628 .ENDIF - 2629 - 2630 ; - 2631 ; THE REMAINDER OF THE CBIOS IS RESERVED UNINITIALIZED - 2632 ; DATA AREA, AND DOES NOT NEED TO BE A PART OF THE - 2633 ; SYSTEM MEMORY IMAGE (THE SPACE MUST BE AVAILABLE, - 2634 ; HOWEVER, BETWEEN "BEGDAT" AND "ENDDAT") - 2635 ; - 2636 - 2637 ; - 2638 ; DISK COMMAND BLOCK - 2639 ; - 0AE9 00 2640 CMD: .DB 0 ; COMMAND READ OR WRITE, - 0AEA 00 2641 UNIT: .DB 0 ; PHYSICAL DRIVE 0->3 - 0AEB 00 2642 HEAD: .DB 0 ; HEAD SEL 0 OR 1 - 0AEC 02 2643 DENS: .DB 2 ; DENSITY - 0AED 09 2644 EOTSEC: .DB 09 ; LAST SECTOR OF TRACK - 0AEE 1B 2645 GAP: .DB 0x1B ; VALUE FOR IRG - 2646 ;SECSIZ: .DB 0x80 ; HOW MANY BYTES TO TRANSFER/4 - 0AEF 00 02 2647 FSECSIZ: .dw 0x0200 ; actual sector size in bytes - 0AF1 FF 2648 DTL: .DB 0x0FF ; SIZE OF SECTOR - 0AF2 7F 2649 SRTHUT: .DB 0x7F ; STEP RATE AND HEAD UNLOAD TIME - 0AF3 05 2650 HLT: .DB 5 ; HEAD LOAD TIME - 0AF4 04 2651 MIN: .DB MINI ; LATCH BIT PATTERN FOR FDC9229 MINITRUE - 0AF5 20 2652 PRE: .DB PRECOMP ; LATCH BIT PATTERN FOR FDC9229 PRECOMP125NS - 2653 ; - 2654 ; FLOPPY STATUS RESULT STORAGE - 2655 ; - 0AF6 00 2656 ST0: .DB 0 ; STORE STATUS 0 - 0AF7 00 2657 ST1: .DB 0 ; ST1 - 0AF8 00 2658 ST2: .DB 0 ; ST2 - 0AF9 00 2659 SCYL: .DB 0 ; TRACK - 0AFA 00 2660 SHEAD: .DB 0 ; HEAD 0 OR 1 - 0AFB 00 2661 SREC: .DB 0 ; SECTOR - 0AFC 00 2662 SNBIT: .DB 0 ; DENSITY - 0AFD 00 2663 ST0A: .DB 0 ; STORE STATUS 0 - 0AFE 00 2664 ST1A: .DB 0 ; ST1 - 0AFF 00 2665 RETRY: .DB 0 ; RETRIES - 0B00 00 2666 RETRY1: .DB 0 ; RETRIES - 2667 - 0B01 00 2668 FLATCH_STORE: .DB 00 ; - 2669 - 0B02 00 00 2670 TRACK: .DW 0 ; TWO BYTES FOR TRACK # (LOGICAL) - 0B04 00 00 2671 PTRACK: .DW 0 ; TWO BYTES FOR TRACK # (PHYSICAL) - 0B06 00 00 2672 FTRACK: .DW 0 ; TWO BYTES FOR TRACK # (HEAD LOCATION) - 2673 - 0B08 01 2674 PAGER: .DB 1 ; COPY OF PAGER BYTE - 0B09 FF 2675 DB_PAGER: .DB 0x0FF ; COPY OF PAGER BYTE (DEBUG) - 0B0A 00 00 2676 SECTOR: .DW 0 ; TWO BYTES FOR SECTOR # (LOGICAL) - 0B0C 00 00 2677 PSECTOR: .DW 0 ; TWO BYTES FOR SECTOR # (PHYSICAL) - 0B0E 00 00 2678 SECST: .DW 0 ; SECTOR IN ROM/RAM START ADDRESS - 0B10 00 00 2679 DMAAD: .DW 0 ; DIRECT MEMORY ADDRESS - 0B12 00 2680 DISKNO: .DB 0 ; DISK NUMBER 0-15 - 0B13 00 00 2681 LBA_TARGET_LO: .DW 0 ; IDE HD PARTITION TARGET SECTOR (LOW 16 BITS) - 0B15 00 00 2682 LBA_TARGET_HI: .DW 0 ; IDE HD PARTITION TARGET SECTOR (HI 16 BITS, 12 USED) - 0B17 00 2683 IDEDEVICE: .DB 0 ; ATAPI DEVICE SELECTION FLAG - 2684 - 0B18 00 2685 IDE_LBA0: .DB 0 ; SET LBA 0:7 - 0B19 00 2686 IDE_LBA1: .DB 0 ; SET LBA 8:15 - 0B1A 00 2687 IDE_LBA2: .DB 0 ; SET LBA 16:23 - 0B1B 00 2688 IDE_LBA3: .DB 0 ; LOWEST 4 BITS USED ONLY TO ENABLE LBA MODE - 0B1C 01 2689 SECTOR_INDEX: .DB 1 ; WHERE 128 BYTE CP/M SECTOR IS IN 512 BYTE IDE HD SECTOR - 2690 ; - 2691 ; SCRATCH RAM AREA FOR BDOS USE - 0B1D 2692 BEGDAT: - 2693 ; = $ ; BEGINNING OF DATA AREA - 0B1D 2694 DIRBF: .DS 128 ; SCRATCH DIRECTORY AREA - 0B9D 2695 ALL00: .DS 65 ; ALLOCATION VECTOR 0 (DSM/8 = 1 BIT PER BLOCK) 44 - 0BDE 2696 ALL01: .DS 33 ; ALLOCATION VECTOR 1 (225/8) - 0BFF 2697 ALL02: .DS 256 ; ALLOCATION VECTOR 2 (511/8) - 0CFF 2698 ALL03: .DS 256 ; ALLOCATION VECTOR 3 (511/8) - 0DFF 2699 ALL04: .DS 65 ; ALLOCATION VECTOR 4 (497/8) - 0E40 2700 ALL05: .DS 65 ; ALLOCATION VECTOR 4 (495/8) - 0E81 2701 ALL06: .DS 65 ; ALLOCATION VECTOR 4 (495/8) - 0EC2 2702 ALL07: .DS 135 ; ALLOCATION VECTOR 7 (495/8) - 0F49 2703 CHK00: .DS 5 ; 720K MEDIA - 0F4E 2704 CHK01: .DS 0 ; NOT USED FOR FIXED MEDIA - 0F4E 2705 CHK02: .DS 0 ; NOT USED FOR FIXED MEDIA - 0F4E 2706 CHK03: .DS 128 ; 8M MEDIA - 0FCE 2707 CHK04: .DS 0 ; NOT USED FOR FIXED MEDIA - 0FCE 2708 CHK05: .DS 0 ; NOT USED FOR FIXED MEDIA - 0FCE 2709 CHK06: .DS 0 ; NOT USED FOR FIXED MEDIA - 0FCE 2710 CHK07: .DS 15 ; 1.44M MEDIA - 2711 ; - 0FDD 2712 CUDISK: .DS 1 ; CURRENT PHYSICAL DISK ID IN BUFFER - 0FDE 01 00 2713 CUSECTOR: .DW 1 ; CURRENT PHYSICAL DISK SECTOR IN BUFFER - 0FE0 02 00 2714 CUTRACK: .DW 2 ; CURRENT PHYSICAL DISK TRACK IN BUFFER - 0FE2 2715 SECTOR_BUFFER: .DS 520 ; STORAGE FOR 512 BYTE IDE HD SECTOR - 11EA 2716 ENDDAT: - 2717 ; .EQU $ ; END OF DATA AREA - 11EA 2718 DSTEMP: - 06CD 2719 DATSIZ = DSTEMP - BEGDAT ; SIZE OF DATA AREA - 2720 - 2721 - 2722 ;dwg; .ORG 0FDFFH - 11EA 00 2723 LASTBYTE: .DB 0 - 2724 - 2725 ; .END - 2726 - 2727 - 2728 - 2729 - 2730 - 11EB 2731 _cbios_end:: - 2732 .area _CODE - 2733 .area _CABS diff --git a/doug/src/cbios.rel b/doug/src/cbios.rel deleted file mode 100755 index 61da9878..00000000 --- a/doug/src/cbios.rel +++ /dev/null @@ -1,958 +0,0 @@ -XL -H 8 areas 4 global symbols -M cbios -O -mz80 -S .__.ABS. Def0000 -A _CODE size 0 flags 0 addr 0 -A _DATA size 0 flags 0 addr 0 -A _OVERLAY size 0 flags 0 addr 0 -A _HOME size 0 flags 0 addr 0 -A _GSINIT size 0 flags 0 addr 0 -A _GSFINAL size 0 flags 0 addr 0 -A _CBIOS size 11EB flags 0 addr 0 -S _cbios_end Def11EB -S _cbios Def0000 -S _cbios_start Def0000 -A _CABS size 0 flags 0 addr 0 -T 00 00 -R 00 00 06 00 -T 00 00 -R 00 00 06 00 -T 00 00 C3 1B 01 C3 46 01 C3 9C 01 C3 -R 00 00 06 00 00 03 06 00 00 06 06 00 00 09 06 00 -T 0A 00 A6 01 C3 B1 01 C3 BC 01 C3 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 13 00 C0 01 C3 C2 01 C3 DA 01 C3 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 1C 00 C4 01 C3 DD 01 C3 E3 01 C3 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 25 00 EC 01 C3 F2 01 C3 D7 03 C3 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 2E 00 BE 01 C3 E9 01 -R 00 00 06 00 00 02 06 00 00 05 06 00 -T 33 00 -R 00 00 06 00 -T 33 00 00 00 00 00 00 00 00 00 1D 0B B2 00 4E 0F -R 00 00 06 00 00 0A 06 00 00 0C 06 00 00 0E 06 00 -T 41 00 DE 0B 00 00 00 00 00 00 00 00 1D 0B 0C 01 -R 00 00 06 00 00 02 06 00 00 0C 06 00 00 0E 06 00 -T 4F 00 CE 0F C2 0E 00 00 00 00 00 00 00 00 1D 0B -R 00 00 06 00 00 02 06 00 00 04 06 00 00 0E 06 00 -T 5D 00 C1 00 4E 0F FF 0B 00 00 00 00 00 00 00 00 -R 00 00 06 00 00 02 06 00 00 04 06 00 00 06 06 00 -T 6B 00 1D 0B B2 00 4E 0F -R 00 00 06 00 00 02 06 00 00 04 06 00 00 06 06 00 -T 71 00 DE 0B 00 00 00 00 00 00 00 00 1D 0B DF 00 -R 00 00 06 00 00 02 06 00 00 0C 06 00 00 0E 06 00 -T 7F 00 CE 0F FF 0D 00 00 00 00 00 00 00 00 1D 0B -R 00 00 06 00 00 02 06 00 00 04 06 00 00 0E 06 00 -T 8D 00 EE 00 CE 0F 40 0E 00 00 00 00 00 00 00 00 -R 00 00 06 00 00 02 06 00 00 04 06 00 00 06 06 00 -T 9B 00 1D 0B FD 00 CE 0F -R 00 00 06 00 00 02 06 00 00 04 06 00 00 06 06 00 -T A1 00 81 0E -R 00 00 06 00 00 02 06 00 -T A3 00 -R 00 00 06 00 -T A3 00 24 00 04 0F 00 5E 01 7F 00 C0 00 20 00 -R 00 00 06 00 -T B0 00 04 00 -R 00 00 06 00 -T B2 00 -R 00 00 06 00 -T B2 00 00 01 04 0F 01 E1 00 FF 00 F0 00 00 00 -R 00 00 06 00 -T BF 00 01 00 -R 00 00 06 00 -T C1 00 -R 00 00 06 00 -T C1 00 00 01 05 1F 01 E1 07 FF 01 F0 00 00 00 -R 00 00 06 00 -T CE 00 F1 03 -R 00 00 06 00 -T D0 00 -R 00 00 06 00 -T D0 00 00 01 05 1F 01 E1 07 FF 01 F0 00 00 00 -R 00 00 06 00 -T DD 00 01 00 -R 00 00 06 00 -T DF 00 -R 00 00 06 00 -T DF 00 00 01 04 0F 01 F1 01 FF 00 F0 00 00 00 -R 00 00 06 00 -T EC 00 01 00 -R 00 00 06 00 -T EE 00 -R 00 00 06 00 -T EE 00 00 01 04 0F 00 FF 01 FF 00 F0 00 00 00 -R 00 00 06 00 -T FB 00 01 00 -R 00 00 06 00 -T FD 00 -R 00 00 06 00 -T FD 00 10 00 03 07 01 1F 00 1F 00 80 00 00 00 -R 00 00 06 00 -T 0A 01 0A 00 -R 00 00 06 00 -T 0C 01 -R 00 00 06 00 -T 0C 01 48 00 04 0F 00 C6 02 FF 00 F0 00 20 00 -R 00 00 06 00 -T 19 01 02 00 -R 00 00 06 00 -T 1B 01 -R 00 00 06 00 -T 1B 01 3E 80 D3 7C 3E 81 D3 78 21 00 00 01 FF 1F -R 00 00 06 00 -T 29 01 3E E5 5D 54 13 77 ED B0 3E 80 D3 7C 3E 00 -R 00 00 06 00 -T 37 01 D3 78 AF 32 03 00 32 04 00 CD C3 05 C3 -R 00 00 06 00 00 0C 06 00 -T 44 01 67 01 -R 00 00 06 00 00 02 06 00 -T 46 01 -R 00 00 06 00 -T 46 01 F3 31 80 00 ED 56 AF D3 7C AF D3 78 21 -R 00 00 06 00 -T 53 01 00 0A 11 00 D0 01 00 08 ED B0 3E 80 D3 7C -R 00 00 06 00 -T 61 01 AF D3 78 CD C3 05 -R 00 00 06 00 00 06 06 00 -T 67 01 -R 00 00 06 00 -T 67 01 3E C3 32 00 00 21 03 00 22 01 00 3E C3 32 -R 00 00 06 00 00 08 06 00 -T 75 01 38 00 21 03 00 22 01 00 32 05 00 21 06 D8 -R 00 00 06 00 00 05 06 00 -T 83 01 22 06 00 01 80 00 CD EC 01 CD BF 07 21 -R 00 00 06 00 00 09 06 00 00 0C 06 00 -T 90 01 AD 0A CD BC 04 3A 04 00 4F C3 00 D0 -R 00 00 06 00 00 02 06 00 00 05 06 00 -T 9C 01 -R 00 00 06 00 -T 9C 01 DB 6D E6 01 CA A5 01 3E FF -R 00 00 06 00 00 07 06 00 -T A5 01 -R 00 00 06 00 -T A5 01 C9 -R 00 00 06 00 -T A6 01 -R 00 00 06 00 -T A6 01 CD 9C 01 FE 00 CA A6 01 DB 68 C9 -R 00 00 06 00 00 03 06 00 00 08 06 00 -T B1 01 -R 00 00 06 00 -T B1 01 DB 6D E6 20 CA B1 01 79 D3 68 C9 -R 00 00 06 00 00 07 06 00 -T BC 01 -R 00 00 06 00 -T BC 01 79 C9 -R 00 00 06 00 -T BE 01 -R 00 00 06 00 -T BE 01 AF C9 -R 00 00 06 00 -T C0 01 -R 00 00 06 00 -T C0 01 79 C9 -R 00 00 06 00 -T C2 01 -R 00 00 06 00 -T C2 01 79 C9 21 00 00 79 FE 07 D0 32 12 0B 6F 26 -R 00 00 06 00 00 0C 06 00 -T D0 01 00 29 29 29 29 11 33 00 19 C9 -R 00 00 06 00 00 08 06 00 -T DA 01 -R 00 00 06 00 -T DA 01 01 00 00 -R 00 00 06 00 -T DD 01 -R 00 00 06 00 -T DD 01 60 69 22 02 0B C9 -R 00 00 06 00 00 05 06 00 -T E3 01 -R 00 00 06 00 -T E3 01 60 69 22 0A 0B C9 -R 00 00 06 00 00 05 06 00 -T E9 01 -R 00 00 06 00 -T E9 01 60 69 C9 -R 00 00 06 00 -T EC 01 -R 00 00 06 00 -T EC 01 69 60 22 10 0B C9 -R 00 00 06 00 00 05 06 00 -T F2 01 -R 00 00 06 00 -T F2 01 F3 3A 12 0B FE 01 CA FE 02 FE 00 CA 5A 02 -R 00 00 06 00 00 04 06 00 00 09 06 00 00 0E 06 00 -T 00 02 FE 02 CA 78 03 FE 03 CA 5A 02 FE 04 CA -R 00 00 06 00 00 05 06 00 00 0A 06 00 -T 0D 02 D6 03 FE 05 CA 5A 02 -R 00 00 06 00 00 02 06 00 00 07 06 00 -T 14 02 -R 00 00 06 00 -T 14 02 2A 02 0B 29 29 29 29 44 4D 2A 0A 0B 09 22 -R 00 00 06 00 00 03 06 00 00 0C 06 00 -T 22 02 0C 0B 2A 0C 0B 29 29 29 29 29 29 29 22 -R 00 00 06 00 00 02 06 00 00 05 06 00 -T 2F 02 0E 0B 3E 00 D3 7C 32 08 0B 21 E2 0F 5D 54 -R 00 00 06 00 00 02 06 00 00 09 06 00 00 0C 06 00 -T 3D 02 2A 0E 0B CD 10 05 CD 04 05 2A -R 00 00 06 00 00 03 06 00 00 06 06 00 00 09 06 00 -T 47 02 10 0B 5D 54 21 E2 0F CD 10 05 3A -R 00 00 06 00 00 02 06 00 00 07 06 00 00 0A 06 00 -T 52 02 12 0B 32 DD 0F 3E 00 C9 -R 00 00 06 00 00 02 06 00 00 05 06 00 -T 5A 02 -R 00 00 06 00 -T 5A 02 CD CB 04 CD D9 04 21 E2 0F 5D 54 2A -R 00 00 06 00 00 03 06 00 00 06 06 00 00 09 06 00 -T 66 02 0E 0B CD 10 05 CD 04 05 2A -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 6F 02 10 0B 5D 54 21 E2 0F CD 10 05 3A -R 00 00 06 00 00 02 06 00 00 07 06 00 00 0A 06 00 -T 7A 02 12 0B 32 DD 0F 3E 00 C9 -R 00 00 06 00 00 02 06 00 00 05 06 00 -T 82 02 -R 00 00 06 00 -T 82 02 3A 02 0B E6 01 32 EB 0A 3A 02 0B CB 3F 32 -R 00 00 06 00 00 03 06 00 00 08 06 00 00 0B 06 00 -T 90 02 04 0B 3A 0A 0B 32 1C 0B CB 3F CB 3F 32 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 9D 02 0C 0B 3A 1C 0B E6 03 32 1C 0B C9 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 0A 06 00 -T A8 02 -R 00 00 06 00 -T A8 02 2A 10 0B 54 5D D5 21 E2 0F 3A 1C 0B 0F 0F -R 00 00 06 00 00 03 06 00 00 09 06 00 00 0C 06 00 -T B6 02 16 00 5F 19 19 D1 CD 10 05 C9 -R 00 00 06 00 00 09 06 00 -T C0 02 -R 00 00 06 00 -T C0 02 21 E2 0F 3A 1C 0B 0F 0F 16 00 5F 19 19 22 -R 00 00 06 00 00 03 06 00 00 06 06 00 -T CE 02 0E 0B 2A 0E 0B 54 5D 2A 10 0B CD -R 00 00 06 00 00 02 06 00 00 05 06 00 00 0A 06 00 -T D9 02 10 05 C9 -R 00 00 06 00 00 02 06 00 -T DC 02 -R 00 00 06 00 -T DC 02 2A 0C 0B 3A DE 0F BD C0 3A DF 0F BC C0 2A -R 00 00 06 00 00 03 06 00 00 06 06 00 00 0B 06 00 -T EA 02 04 0B 3A E0 0F BD C0 3A E1 0F BC C0 2A -R 00 00 06 00 00 02 06 00 00 05 06 00 00 0A 06 00 -T F7 02 12 0B 3A DD 0F BD C9 -R 00 00 06 00 00 02 06 00 00 05 06 00 -T FE 02 -R 00 00 06 00 -T FE 02 F3 21 00 00 39 22 64 0A 31 63 0A CD 82 02 -R 00 00 06 00 00 08 06 00 00 0B 06 00 00 0E 06 00 -T 0C 03 CD 1A 03 CD A8 02 3A F7 0A -R 00 00 06 00 00 03 06 00 00 06 06 00 00 09 06 00 -T 15 03 -R 00 00 06 00 -T 15 03 ED 7B 64 0A C9 -R 00 00 06 00 00 04 06 00 -T 1A 03 -R 00 00 06 00 -T 1A 03 3E 00 32 F7 0A CD DC 02 CA 65 03 3E 14 32 -R 00 00 06 00 00 05 06 00 00 08 06 00 00 0B 06 00 -T 28 03 FF 0A 3E 02 32 00 0B -R 00 00 06 00 00 02 06 00 00 07 06 00 -T 2F 03 -R 00 00 06 00 -T 2F 03 CD 1E 08 3A F6 0A E6 F8 47 3A F7 0A B0 CA -R 00 00 06 00 00 03 06 00 00 06 06 00 00 0C 06 00 -T 3D 03 65 03 3A FF 0A 3D 32 FF 0A C2 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 09 06 00 -T 47 03 2F 03 CD 61 09 3E 14 32 FF 0A 3A -R 00 00 06 00 00 02 06 00 00 05 06 00 00 0A 06 00 -T 52 03 00 0B 3D 32 00 0B C2 2F 03 21 FF FF 22 -R 00 00 06 00 00 02 06 00 00 06 06 00 00 09 06 00 -T 5F 03 DE 0F 22 E0 0F C9 -R 00 00 06 00 00 02 06 00 00 05 06 00 -T 65 03 -R 00 00 06 00 -T 65 03 2A 0C 0B 22 DE 0F 2A 04 0B 22 -R 00 00 06 00 00 03 06 00 00 06 06 00 00 09 06 00 -T 6F 03 E0 0F 3A 12 0B 32 DD 0F C9 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 78 03 -R 00 00 06 00 -T 78 03 F3 21 00 00 39 22 64 0A 31 63 0A CD 16 05 -R 00 00 06 00 00 08 06 00 00 0B 06 00 00 0E 06 00 -T 86 03 CD 6A 05 D2 96 03 CD A8 02 ED 7B -R 00 00 06 00 00 03 06 00 00 06 06 00 00 09 06 00 -T 91 03 64 0A 3E 00 C9 -R 00 00 06 00 00 02 06 00 -T 96 03 -R 00 00 06 00 -T 96 03 ED 7B 64 0A 3E FF C9 -R 00 00 06 00 00 04 06 00 -T 9D 03 -R 00 00 06 00 -T 9D 03 3E FF 32 FF 0A -R 00 00 06 00 00 05 06 00 -T A2 03 -R 00 00 06 00 -T A2 03 3E 10 32 17 0B F3 21 00 00 39 22 64 0A 31 -R 00 00 06 00 00 05 06 00 00 0D 06 00 -T B0 03 63 0A CD 16 05 CD DF 06 D2 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T B9 03 C5 03 CD A8 02 ED 7B 64 0A 3E 00 C9 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 09 06 00 -T C5 03 -R 00 00 06 00 -T C5 03 3A FF 0A 3D 32 FF 0A C2 A2 03 ED 7B -R 00 00 06 00 00 03 06 00 00 07 06 00 00 0A 06 00 -T D1 03 64 0A 3E FF C9 -R 00 00 06 00 00 02 06 00 -T D6 03 -R 00 00 06 00 -T D6 03 C9 -R 00 00 06 00 -T D7 03 -R 00 00 06 00 -T D7 03 F3 3A 12 0B FE 01 CA 25 04 FE 00 CA FD 03 -R 00 00 06 00 00 04 06 00 00 09 06 00 00 0E 06 00 -T E5 03 FE 02 CA 66 04 FE 03 CA FD 03 FE 04 CA -R 00 00 06 00 00 05 06 00 00 0A 06 00 -T F2 03 BB 04 -R 00 00 06 00 00 02 06 00 -T F4 03 -R 00 00 06 00 -T F4 03 21 8C 0A CD BC 04 3E 01 C9 -R 00 00 06 00 00 03 06 00 00 06 06 00 -T FD 03 -R 00 00 06 00 -T FD 03 21 E2 0F 5D 54 2A 10 0B CD 10 05 CD -R 00 00 06 00 00 03 06 00 00 08 06 00 00 0B 06 00 -T 09 04 CB 04 CD D9 04 2A 0E 0B 5D 54 21 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 14 04 E2 0F CD 10 05 CD 04 05 3A -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 1D 04 12 0B 32 DD 0F 3E 00 C9 -R 00 00 06 00 00 02 06 00 00 05 06 00 -T 25 04 -R 00 00 06 00 -T 25 04 F3 21 00 00 39 22 64 0A 31 63 0A CD 82 02 -R 00 00 06 00 00 08 06 00 00 0B 06 00 00 0E 06 00 -T 33 04 CD 1A 03 3A F7 0A C2 5E 04 -R 00 00 06 00 00 03 06 00 00 06 06 00 00 09 06 00 -T 3C 04 -R 00 00 06 00 -T 3C 04 CD C0 02 3E 14 32 FF 0A -R 00 00 06 00 00 03 06 00 00 08 06 00 -T 44 04 -R 00 00 06 00 -T 44 04 CD 26 08 3A F6 0A E6 F8 47 3A F7 0A B0 CA -R 00 00 06 00 00 03 06 00 00 06 06 00 00 0C 06 00 -T 52 04 5E 04 3A FF 0A 3D 32 FF 0A C2 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 09 06 00 -T 5C 04 44 04 -R 00 00 06 00 00 02 06 00 -T 5E 04 -R 00 00 06 00 -T 5E 04 ED 7B 64 0A 3A F7 0A C9 -R 00 00 06 00 00 04 06 00 00 07 06 00 -T 66 04 -R 00 00 06 00 -T 66 04 F3 21 00 00 39 22 64 0A 31 63 0A CD 16 05 -R 00 00 06 00 00 08 06 00 00 0B 06 00 00 0E 06 00 -T 74 04 CD 6A 05 D2 87 04 CD C0 02 CD -R 00 00 06 00 00 03 06 00 00 06 06 00 00 09 06 00 -T 7E 04 9F 05 ED 7B 64 0A 3E 00 C9 -R 00 00 06 00 00 02 06 00 00 06 06 00 -T 87 04 -R 00 00 06 00 -T 87 04 ED 7B 64 0A 3E FF C9 -R 00 00 06 00 00 04 06 00 -T 8E 04 -R 00 00 06 00 -T 8E 04 3E 10 32 17 0B F3 21 00 00 39 22 64 0A 31 -R 00 00 06 00 00 05 06 00 00 0D 06 00 -T 9C 04 63 0A CD 16 05 CD DF 06 D2 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T A5 04 B4 04 CD C0 02 CD 3C 07 ED 7B -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T AF 04 64 0A 3E 00 C9 -R 00 00 06 00 00 02 06 00 -T B4 04 -R 00 00 06 00 -T B4 04 ED 7B 64 0A 3E FF C9 -R 00 00 06 00 00 04 06 00 -T BB 04 -R 00 00 06 00 -T BB 04 C9 -R 00 00 06 00 -T BC 04 -R 00 00 06 00 -T BC 04 7E FE FF CA CA 04 4F CD B1 01 23 C3 BC 04 -R 00 00 06 00 00 06 06 00 00 0A 06 00 00 0E 06 00 -T CA 04 -R 00 00 06 00 -T CA 04 C9 -R 00 00 06 00 -T CB 04 -R 00 00 06 00 -T CB 04 2A 0A 0B 29 29 29 29 29 29 29 22 0E 0B C9 -R 00 00 06 00 00 03 06 00 00 0D 06 00 -T D9 04 -R 00 00 06 00 -T D9 04 2A 02 0B 3A 12 0B FE 05 CA F3 04 FE 06 CA -R 00 00 06 00 00 03 06 00 00 06 06 00 00 0B 06 00 -T E7 04 F3 04 E6 01 0F B5 D3 78 32 08 0B C9 -R 00 00 06 00 00 02 06 00 00 0B 06 00 -T F3 04 -R 00 00 06 00 -T F3 04 3E 05 E6 01 0F B5 E6 7F D3 7C 32 08 0B 32 -R 00 00 06 00 00 0D 06 00 -T 01 05 09 0B C9 -R 00 00 06 00 00 02 06 00 -T 04 05 -R 00 00 06 00 -T 04 05 3E 80 D3 7C 3E 00 D3 78 32 08 0B C9 -R 00 00 06 00 00 0B 06 00 -T 10 05 -R 00 00 06 00 -T 10 05 01 80 00 ED B0 C9 -R 00 00 06 00 -T 16 05 -R 00 00 06 00 -T 16 05 3A 02 0B 67 3A 0A 0B 6F CD 61 05 CD -R 00 00 06 00 00 03 06 00 00 07 06 00 00 0B 06 00 -T 22 05 61 05 3A 03 0B CB 27 CB 27 CB 27 CB 27 CB -R 00 00 06 00 00 02 06 00 00 05 06 00 -T 30 05 27 CB 27 B4 67 3A 03 0B CB 3F CB 3F 32 -R 00 00 06 00 00 08 06 00 -T 3D 05 15 0B 7D 32 13 0B 7C 32 14 0B 3E 00 32 -R 00 00 06 00 00 02 06 00 00 06 06 00 00 0A 06 00 -T 4A 05 16 0B 2A 13 0B 22 0C 0B 2A -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 53 05 15 0B 22 04 0B 3A 0A 0B E6 03 32 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 5E 05 1C 0B C9 -R 00 00 06 00 00 02 06 00 -T 61 05 -R 00 00 06 00 -T 61 05 37 3F 7C 1F 67 7D 1F 6F C9 -R 00 00 06 00 -T 6A 05 -R 00 00 06 00 -T 6A 05 CD DC 02 CA 8B 05 CD F3 05 D0 CD -R 00 00 06 00 00 03 06 00 00 06 06 00 00 09 06 00 -T 75 05 66 06 3E 20 D3 27 -R 00 00 06 00 00 02 06 00 -T 7B 05 -R 00 00 06 00 -T 7B 05 CD F3 05 D0 CD 0F 06 D0 CD 22 06 D0 CD -R 00 00 06 00 00 03 06 00 00 07 06 00 00 0B 06 00 -T 88 05 3C 06 37 -R 00 00 06 00 00 02 06 00 -T 8B 05 -R 00 00 06 00 -T 8B 05 2A 0C 0B 22 DE 0F 2A 04 0B 22 -R 00 00 06 00 00 03 06 00 00 06 06 00 00 09 06 00 -T 95 05 E0 0F 3A 12 0B 32 DD 0F 37 C9 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 9F 05 -R 00 00 06 00 -T 9F 05 CD F3 05 D0 CD 66 06 3E 30 D3 27 CD F3 05 -R 00 00 06 00 00 03 06 00 00 07 06 00 00 0E 06 00 -T AD 05 D0 CD 0F 06 D0 CD 22 06 D0 CD 50 06 CD -R 00 00 06 00 00 04 06 00 00 08 06 00 00 0C 06 00 -T BA 05 F3 05 D0 CD 0F 06 D0 37 C9 -R 00 00 06 00 00 02 06 00 00 06 06 00 -T C3 05 -R 00 00 06 00 -T C3 05 3E 06 D3 2E 3E 02 D3 2E CD F3 05 C9 -R 00 00 06 00 00 0B 06 00 -T CF 05 -R 00 00 06 00 -T CF 05 11 00 00 -R 00 00 06 00 -T D2 05 -R 00 00 06 00 -T D2 05 06 F0 -R 00 00 06 00 -T D4 05 -R 00 00 06 00 -T D4 05 10 FE 13 7A B3 28 08 DB 27 E6 80 20 F1 37 -R 00 00 06 00 -T E2 05 C9 -R 00 00 06 00 -T E3 05 -R 00 00 06 00 -T E3 05 AF C9 -R 00 00 06 00 -T E5 05 -R 00 00 06 00 -T E5 05 DB 27 E6 08 28 FA C9 -R 00 00 06 00 -T EC 05 -R 00 00 06 00 -T EC 05 DB 27 E6 08 20 FA C9 -R 00 00 06 00 -T F3 05 -R 00 00 06 00 -T F3 05 11 00 00 -R 00 00 06 00 -T F6 05 -R 00 00 06 00 -T F6 05 06 05 -R 00 00 06 00 -T F8 05 -R 00 00 06 00 -T F8 05 05 C2 F8 05 13 7A B3 CA 0D 06 DB 27 E6 C0 -R 00 00 06 00 00 04 06 00 00 0A 06 00 -T 06 06 EE 40 C2 F6 05 37 C9 -R 00 00 06 00 00 05 06 00 -T 0D 06 -R 00 00 06 00 -T 0D 06 AF C9 -R 00 00 06 00 -T 0F 06 -R 00 00 06 00 -T 0F 06 37 DB 27 47 E6 01 37 C8 78 E6 20 37 C2 -R 00 00 06 00 -T 1C 06 20 06 DB 21 -R 00 00 06 00 00 02 06 00 -T 20 06 -R 00 00 06 00 -T 20 06 B7 C9 -R 00 00 06 00 -T 22 06 -R 00 00 06 00 -T 22 06 11 00 00 -R 00 00 06 00 -T 25 06 -R 00 00 06 00 -T 25 06 06 05 -R 00 00 06 00 -T 27 06 -R 00 00 06 00 -T 27 06 05 C2 27 06 13 7A B3 CA 3A 06 DB 27 E6 08 -R 00 00 06 00 00 04 06 00 00 0A 06 00 -T 35 06 CA 25 06 37 C9 -R 00 00 06 00 00 03 06 00 -T 3A 06 -R 00 00 06 00 -T 3A 06 AF C9 -R 00 00 06 00 -T 3C 06 -R 00 00 06 00 -T 3C 06 E5 21 E2 0F 06 00 -R 00 00 06 00 00 04 06 00 -T 42 06 -R 00 00 06 00 -T 42 06 DB 20 77 DB 28 23 77 23 05 C2 42 06 E1 C9 -R 00 00 06 00 00 0C 06 00 -T 50 06 -R 00 00 06 00 -T 50 06 E5 21 E2 0F 06 00 -R 00 00 06 00 00 04 06 00 -T 56 06 -R 00 00 06 00 -T 56 06 23 7E 2B D3 28 7E D3 20 23 23 05 C2 56 06 -R 00 00 06 00 00 0E 06 00 -T 64 06 E1 C9 -R 00 00 06 00 -T 66 06 -R 00 00 06 00 -T 66 06 3A 13 0B 32 18 0B 3A 14 0B 32 -R 00 00 06 00 00 03 06 00 00 06 06 00 00 09 06 00 -T 70 06 19 0B 3A 15 0B 32 1A 0B 3A -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 79 06 16 0B E6 0F C6 E0 32 1B 0B 3E 01 D3 22 3A -R 00 00 06 00 00 02 06 00 00 09 06 00 -T 87 06 18 0B D3 23 3A 19 0B D3 24 3A 1A 0B D3 25 -R 00 00 06 00 00 02 06 00 00 07 06 00 00 0C 06 00 -T 95 06 3A 1B 0B E6 0F F6 E0 D3 26 C9 -R 00 00 06 00 00 03 06 00 -T 9F 06 -R 00 00 06 00 -T 9F 06 3E 0E D3 2E CD D7 09 3E 0A D3 2E CD CF 05 -R 00 00 06 00 00 07 06 00 00 0E 06 00 -T AD 06 D0 CD D7 06 CD D7 09 CD B8 06 C9 -R 00 00 06 00 00 04 06 00 00 07 06 00 00 0A 06 00 -T B8 06 -R 00 00 06 00 -T B8 06 21 80 0A CD 7D 07 CD CF 05 D0 06 00 -R 00 00 06 00 00 03 06 00 00 06 06 00 00 09 06 00 -T C4 06 -R 00 00 06 00 -T C4 06 DB 20 DD 23 DB 28 DD 23 10 F6 ED 67 DB 27 -R 00 00 06 00 -T D2 06 E6 01 20 E2 C9 -R 00 00 06 00 -T D7 06 -R 00 00 06 00 -T D7 06 3A 17 0B F6 A0 D3 26 C9 -R 00 00 06 00 00 03 06 00 -T DF 06 -R 00 00 06 00 -T DF 06 CD DC 02 CA 28 07 3A 13 0B 32 -R 00 00 06 00 00 03 06 00 00 06 06 00 00 09 06 00 -T E9 06 6D 0A 3A 14 0B 32 6C 0A 3A -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T F2 06 15 0B 32 6B 0A 3A 16 0B 32 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T FB 06 6A 0A CD B8 06 21 68 0A CD -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 04 07 7D 07 CD CF 05 D0 06 00 DD 21 E2 0F DB 27 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 0C 06 00 -T 12 07 E6 08 FE 08 20 10 -R 00 00 06 00 -T 18 07 -R 00 00 06 00 -T 18 07 DB 20 DD 77 00 DD 23 DB 28 DD 77 00 DD 23 -R 00 00 06 00 -T 26 07 10 F0 -R 00 00 06 00 -T 28 07 -R 00 00 06 00 -T 28 07 2A 0C 0B 22 DE 0F 2A 04 0B 22 -R 00 00 06 00 00 03 06 00 00 06 06 00 00 09 06 00 -T 32 07 E0 0F 3A 12 0B 32 DD 0F 37 C9 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 3C 07 -R 00 00 06 00 -T 3C 07 3A 13 0B 32 79 0A 3A 14 0B 32 -R 00 00 06 00 00 03 06 00 00 06 06 00 00 09 06 00 -T 46 07 78 0A 3A 15 0B 32 77 0A 3A -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 4F 07 16 0B 32 76 0A CD B8 06 21 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 58 07 74 0A CD 7D 07 CD CF 05 D0 06 00 DD 21 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 65 07 E2 0F -R 00 00 06 00 00 02 06 00 -T 67 07 -R 00 00 06 00 -T 67 07 DB 27 DD 7E 00 F5 DD 23 DD 7E 00 D3 28 F1 -R 00 00 06 00 -T 75 07 D3 20 DD 23 10 EC 37 C9 -R 00 00 06 00 -T 7D 07 -R 00 00 06 00 -T 7D 07 CD CF 05 D0 CD EC 05 3E 0A D3 2E 3E 00 D3 -R 00 00 06 00 00 03 06 00 00 07 06 00 -T 8B 07 21 3E 00 D3 22 3E 00 D3 23 3E 00 D3 24 3E -R 00 00 06 00 -T 99 07 60 D3 25 3A 17 0B D3 26 3E A0 D3 27 CD -R 00 00 06 00 00 06 06 00 -T A6 07 E5 05 06 06 -R 00 00 06 00 00 02 06 00 -T AA 07 -R 00 00 06 00 -T AA 07 7E 57 23 7E D3 28 7A D3 20 23 DB 2E 10 F2 -R 00 00 06 00 -T B8 07 CD CF 05 D0 DB 2E C9 -R 00 00 06 00 00 03 06 00 -T BF 07 -R 00 00 06 00 -T BF 07 3E 02 F6 20 F6 40 F6 80 32 01 0B 3E 01 32 -R 00 00 06 00 00 0B 06 00 -T CD 07 EA 0A 3E 02 32 EC 0A 3E 09 87 32 ED 0A 3E -R 00 00 06 00 00 02 06 00 00 07 06 00 00 0D 06 00 -T DB 07 7F 32 F2 0A 3E 05 32 F3 0A 3E 0D 32 EE 0A -R 00 00 06 00 00 04 06 00 00 09 06 00 00 0E 06 00 -T E9 07 CD E4 09 CD E4 09 CD E4 09 CD -R 00 00 06 00 00 03 06 00 00 06 06 00 00 09 06 00 -T F3 07 E4 09 CD E4 09 CD E4 09 21 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T FC 07 01 0B CB 8E CD 18 08 00 00 3E 00 32 04 0B -R 00 00 06 00 00 02 06 00 00 07 06 00 00 0E 06 00 -T 0A 08 CD 24 09 00 00 21 01 0B CB CE CD 18 08 C9 -R 00 00 06 00 00 03 06 00 00 08 06 00 00 0D 06 00 -T 18 08 -R 00 00 06 00 -T 18 08 3A 01 0B D3 3A C9 -R 00 00 06 00 00 03 06 00 -T 1E 08 -R 00 00 06 00 -T 1E 08 3E 46 32 E9 0A C3 2E 08 -R 00 00 06 00 00 05 06 00 00 08 06 00 -T 26 08 -R 00 00 06 00 -T 26 08 3E 45 32 E9 0A C3 2E 08 -R 00 00 06 00 00 05 06 00 00 08 06 00 -T 2E 08 -R 00 00 06 00 -T 2E 08 21 01 0B CB CE CD 18 08 CD E4 09 FE FF CA -R 00 00 06 00 00 03 06 00 00 08 06 00 00 0B 06 00 -T 3C 08 75 08 3A EA 0A E6 03 47 3A EB 0A E6 01 17 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 0B 06 00 -T 4A 08 17 B0 32 EA 0A 21 01 0B CB 8E CD 18 08 3E -R 00 00 06 00 00 05 06 00 00 08 06 00 00 0D 06 00 -T 58 08 03 CD C2 09 3A F2 0A CD C2 09 3A -R 00 00 06 00 00 04 06 00 00 07 06 00 00 0A 06 00 -T 63 08 F3 0A CD C2 09 CD 24 09 C2 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 6C 08 75 08 3A E9 0A B7 C3 A4 08 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 09 06 00 -T 75 08 -R 00 00 06 00 -T 75 08 21 01 0B CB CE CD 18 08 F6 FF C9 -R 00 00 06 00 00 03 06 00 00 08 06 00 -T 80 08 -R 00 00 06 00 -T 80 08 0E 07 21 F6 0A -R 00 00 06 00 00 05 06 00 -T 85 08 -R 00 00 06 00 -T 85 08 CD 30 0A 77 23 0D C2 85 08 3A F6 0A E6 F8 -R 00 00 06 00 00 03 06 00 00 09 06 00 00 0C 06 00 -T 93 08 47 3A F7 0A B0 -R 00 00 06 00 00 04 06 00 -T 98 08 -R 00 00 06 00 -T 98 08 CD E4 09 21 01 0B CB CE CD 18 08 C9 -R 00 00 06 00 00 03 06 00 00 06 06 00 00 0B 06 00 -T A4 08 -R 00 00 06 00 -T A4 08 11 38 00 21 1E 09 01 03 00 3A E9 0A E6 01 -R 00 00 06 00 00 06 06 00 00 0C 06 00 -T B2 08 CA B6 08 09 -R 00 00 06 00 00 03 06 00 -T B6 08 -R 00 00 06 00 -T B6 08 ED B0 21 E2 0F ED 5B EF 0A 43 0E 37 3A -R 00 00 06 00 00 05 06 00 00 09 06 00 -T C3 08 E9 0A CD C2 09 3A EA 0A CD -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T CC 08 C2 09 3A 04 0B CD C2 09 3A -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T D5 08 EB 0A CD C2 09 3A 0C 0B 3C CD -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T DF 08 C2 09 3A EC 0A CD C2 09 3A -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T E8 08 ED 0A CD C2 09 3A EE 0A CD -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T F1 08 C2 09 3A F1 0A CD AF 09 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T F9 08 -R 00 00 06 00 -T F9 08 -R 00 00 06 00 -T F9 08 FB 76 C2 F9 08 -R 00 00 06 00 00 05 06 00 -T FE 08 -R 00 00 06 00 -T FE 08 FB 76 C2 FE 08 -R 00 00 06 00 00 05 06 00 -T 03 09 -R 00 00 06 00 -T 03 09 21 01 0B CB C6 CD 18 08 00 00 CB 86 CD -R 00 00 06 00 00 03 06 00 00 08 06 00 -T 10 09 18 08 00 00 00 00 CB CE CD 18 08 C3 80 08 -R 00 00 06 00 00 02 06 00 00 0B 06 00 00 0E 06 00 -T 1E 09 ED A2 C9 -R 00 00 06 00 -T 21 09 -R 00 00 06 00 -T 21 09 ED A3 C9 -R 00 00 06 00 -T 24 09 -R 00 00 06 00 -T 24 09 -R 00 00 06 00 -T 24 09 3A 06 0B 4F 3A 04 0B B7 CA 4A 09 B9 CA -R 00 00 06 00 00 03 06 00 00 07 06 00 00 0B 06 00 -T 31 09 5A 09 32 06 0B 3E 0F CD C2 09 3A -R 00 00 06 00 00 02 06 00 00 05 06 00 00 0A 06 00 -T 3C 09 EA 0A CD C2 09 3A 04 0B CD -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 45 09 C2 09 C3 5A 09 -R 00 00 06 00 00 02 06 00 00 05 06 00 -T 4A 09 -R 00 00 06 00 -T 4A 09 3E 00 32 06 0B 3E 07 CD C2 09 3A EA 0A CD -R 00 00 06 00 00 05 06 00 00 0A 06 00 00 0D 06 00 -T 58 09 C2 09 -R 00 00 06 00 00 02 06 00 -T 5A 09 -R 00 00 06 00 -T 5A 09 CD F6 09 CD E4 09 C9 -R 00 00 06 00 00 03 06 00 00 06 06 00 -T 61 09 -R 00 00 06 00 -T 61 09 F5 E5 CD E4 09 CD E4 09 CD E4 09 CD -R 00 00 06 00 00 05 06 00 00 08 06 00 00 0B 06 00 -T 6D 09 E4 09 CD E4 09 CD E4 09 21 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 76 09 01 0B CB 8E CD 18 08 00 00 CD 4A 09 CD -R 00 00 06 00 00 02 06 00 00 07 06 00 00 0C 06 00 -T 83 09 F6 09 CD F6 09 CD F6 09 CD -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 8C 09 F6 09 CD 4A 09 CD F6 09 CD -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 95 09 F6 09 CD F6 09 CD F6 09 CD -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 9E 09 24 09 CD F6 09 CD F6 09 CD -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T A7 09 F6 09 CD F6 09 E1 F1 C9 -R 00 00 06 00 00 02 06 00 00 05 06 00 -T AF 09 -R 00 00 06 00 -T AF 09 F5 -R 00 00 06 00 -T B0 09 -R 00 00 06 00 -T B0 09 DB 36 E6 80 CA B0 09 DB 36 E6 40 C4 06 0A -R 00 00 06 00 00 07 06 00 00 0E 06 00 -T BE 09 F1 D3 37 C9 -R 00 00 06 00 -T C2 09 -R 00 00 06 00 -T C2 09 F5 -R 00 00 06 00 -T C3 09 -R 00 00 06 00 -T C3 09 DB 36 E6 80 CA C3 09 DB 36 E6 40 C4 06 0A -R 00 00 06 00 00 07 06 00 00 0E 06 00 -T D1 09 F1 D3 37 C3 D7 09 -R 00 00 06 00 00 06 06 00 -T D7 09 -R 00 00 06 00 -T D7 09 DD E5 DD E1 DD E5 DD E1 -R 00 00 06 00 -T DF 09 -R 00 00 06 00 -T DF 09 DD E5 DD E1 C9 -R 00 00 06 00 -T E4 09 -R 00 00 06 00 -T E4 09 DB 36 E6 80 CA E4 09 DB 36 E6 40 C2 F5 09 -R 00 00 06 00 00 07 06 00 00 0E 06 00 -T F2 09 CD 12 0A -R 00 00 06 00 00 03 06 00 -T F5 09 -R 00 00 06 00 -T F5 09 C9 -R 00 00 06 00 -T F6 09 -R 00 00 06 00 -T F6 09 21 00 00 -R 00 00 06 00 -T F9 09 -R 00 00 06 00 -T F9 09 00 00 00 00 2D C2 F9 09 25 C2 F9 09 C9 -R 00 00 06 00 00 08 06 00 00 0C 06 00 -T 06 0A -R 00 00 06 00 -T 06 0A DB 37 DB 36 E6 80 CA 06 0A 3E FF C9 -R 00 00 06 00 00 09 06 00 -T 12 0A -R 00 00 06 00 -T 12 0A 3E 08 CD C2 09 CD 30 0A 32 FD 0A E6 C0 FE -R 00 00 06 00 00 05 06 00 00 08 06 00 00 0B 06 00 -T 20 0A 80 CA 2F 0A CD 30 0A 32 FE 0A 3A -R 00 00 06 00 00 04 06 00 00 07 06 00 00 0A 06 00 -T 2B 0A FD 0A E6 C0 -R 00 00 06 00 00 02 06 00 -T 2F 0A -R 00 00 06 00 -T 2F 0A C9 -R 00 00 06 00 -T 30 0A -R 00 00 06 00 -T 30 0A DB 36 E6 80 CA 30 0A DB 36 E6 40 CC 06 0A -R 00 00 06 00 00 07 06 00 00 0E 06 00 -T 3E 0A DB 37 C3 D7 09 00 00 00 00 00 00 00 00 00 -R 00 00 06 00 00 05 06 00 -T 4C 0A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -R 00 00 06 00 -T 5A 0A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -R 00 00 06 00 -T 68 0A -R 00 00 06 00 -T 68 0A A8 00 00 00 00 01 00 00 00 01 00 00 -R 00 00 06 00 -T 74 0A -R 00 00 06 00 -T 74 0A 2A 00 00 00 00 11 00 00 01 00 00 00 -R 00 00 06 00 -T 80 0A -R 00 00 06 00 -T 80 0A 03 00 00 00 11 00 00 00 00 00 00 00 -R 00 00 06 00 -T 8C 0A -R 00 00 06 00 -T 8C 0A 0D 0A 45 52 52 4F 52 3A 20 57 52 49 54 45 -R 00 00 06 00 -T 9A 0A 20 54 4F 20 52 45 41 44 20 4F 4E 4C 59 20 -R 00 00 06 00 -T A8 0A 44 49 53 4B FF -R 00 00 06 00 -T AD 0A -R 00 00 06 00 -T AD 0A 0D 0A 43 50 2F 4D 2D 38 30 20 32 2E 32 43 -R 00 00 06 00 -T BB 0A 20 28 4A 43 30 37 30 35 2D 31 29 20 66 6F -R 00 00 06 00 -T C9 0A 72 20 4E 38 56 45 4D 20 2D 20 57 2F 49 44 -R 00 00 06 00 -T D7 0A 45 20 46 4C 4F 50 50 59 20 31 2E 34 34 4D -R 00 00 06 00 -T E5 0A 20 0D 0A FF 00 00 00 02 09 1B 00 02 FF 7F -R 00 00 06 00 -T F3 0A 05 04 20 00 00 00 00 00 00 00 00 00 00 00 -R 00 00 06 00 -T 01 0B 00 00 00 00 00 00 00 01 FF 00 00 00 00 -R 00 00 06 00 -T 0E 0B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -R 00 00 06 00 -T 1C 0B 01 -R 00 00 06 00 -T 1D 0B -R 00 00 06 00 -T 1D 0B -R 00 00 06 00 -T 9D 0B -R 00 00 06 00 -T DE 0B -R 00 00 06 00 -T FF 0B -R 00 00 06 00 -T FF 0C -R 00 00 06 00 -T FF 0D -R 00 00 06 00 -T 40 0E -R 00 00 06 00 -T 81 0E -R 00 00 06 00 -T C2 0E -R 00 00 06 00 -T 49 0F -R 00 00 06 00 -T 4E 0F -R 00 00 06 00 -T 4E 0F -R 00 00 06 00 -T 4E 0F -R 00 00 06 00 -T CE 0F -R 00 00 06 00 -T CE 0F -R 00 00 06 00 -T CE 0F -R 00 00 06 00 -T CE 0F -R 00 00 06 00 -T DD 0F -R 00 00 06 00 -T DE 0F 01 00 02 00 -R 00 00 06 00 -T E2 0F -R 00 00 06 00 -T EA 11 -R 00 00 06 00 -T EA 11 -R 00 00 06 00 -T EA 11 00 -R 00 00 06 00 -T EB 11 -R 00 00 06 00 diff --git a/doug/src/cbios.s b/doug/src/cbios.s deleted file mode 100755 index ea7fb0e5..00000000 --- a/doug/src/cbios.s +++ /dev/null @@ -1,2733 +0,0 @@ - .title cbios.s derived from cbios.asm - .sbttl by Douglas Goodall for N8VEM use - - .module cbios - .optsdcc -mz80 - -;-------------------------------------------------------- -; Public variables in this module -;-------------------------------------------------------- - .globl _cbios -;-------------------------------------------------------- -; special function registers -;-------------------------------------------------------- -;-------------------------------------------------------- -; ram data -;-------------------------------------------------------- - .area _DATA -;-------------------------------------------------------- -; overlayable items in ram -;-------------------------------------------------------- - .area _OVERLAY -;-------------------------------------------------------- -; external initialized ram data -;-------------------------------------------------------- -;-------------------------------------------------------- -; global & static initialisations -;-------------------------------------------------------- - .area _HOME - .area _GSINIT - .area _GSFINAL - .area _GSINIT -;-------------------------------------------------------- -; Home -;-------------------------------------------------------- - .area _HOME - .area _HOME -;-------------------------------------------------------- -; code -;-------------------------------------------------------- - -; .area _CODE - .area _CBIOS - -_cbios_start:: -_cbios: - -; CBIOS FOR N8VEM -; -; Supports: Floppy, IDE HDD, ATAPI ZIP, RAM & ROM DRIVES, on board 16550, DSKY & VDU CARD -; -; BY ANDREW LYNCH, WITH INPUT FROM MANY SOURCES -; -; DATA CONSTANTS -;__________________________________________________________________________________________________ -FALSE = 0 -TRUE = 1 - -; LIST OF CONDITIONAL ASSEMBLY INSTRUCTIONS - -CONDIDESOFT = FALSE ; IF NO IDE DRIVE, HAS A SIGNIFICANT DELAY ON SOFT BOOT (TRUE) OR QUICK (FALSE) -CONDSHORTMSG = TRUE ; TRUE FOR ORIGINAL WARM BOOT SIGNON, FALSE FOR SHORTER ONE WITH LESS -CONDSUPERSUB = TRUE ; TRUE FOR NO SUPERSUB AUTOEXEC, FALSE TO RUN SUPERSUB AUTOEXEC -CONDABONLY = TRUE ; TRUE FOR ORIGINAL, FALSE TO ONLY HAVE DRIVE A AND B - -CONDUSEVDU = FALSE ; TRUE FOR USE VDU CARD, FALSE TO USE SERIAL PORT (FOR CONSOLE) -CONDUSEFLOPPY = FALSE ; TRUE FOR USE FLOPPY, FALSE FOR NO FLOPPY DRIVE -COND144FLOPPY = FALSE ; TRUE FOR 1.44Mb FLOPPY ON DRIVE G: -CONDUSEATAPI = FALSE ; TRUE FOR USE ZIP DISK, FALSE FOR NO ZIP DISK -CONDUSEDSKY = FALSE ; TRUE FOR USE DSKY, FALSE FOR NO DSKY - -; POINTERS TO VDU ROUTINES IN HIGH ROM BANK (NOT NEEDED IF NOT USING VDU CARD) - -VDU_INIT = 0x0100 ; VECTOR TO VDU INIT CODE -IS_KBHIT = 0x0395 ; VECTOR TO KB HIT CODE -GET_KEY = 0x039C ; VECTOR TO GET KEY CODE -CHARIN = 0x011B ; VECTOR TO CHARIN CODE -PR_OUTCHAR = 0x0CD6 ; VECTOR TO PRINTER CODE - -; -MSIZE = 59 ;CP/M VERSION MEMORY SIZE IN KILOBYTES -; -; "BIAS" IS ADDRESS OFFSET FROM 3400H FOR MEMORY SYSTEMS -; THAN 16K (REFERRED TO AS "B" THROUGHOUT THE TEXT) -; -BIAS = (MSIZE-20)*1024 ; -CCP = 0x3400+BIAS ; BASE OF CCP -BDOS = CCP+0x806 ; BASE OF BDOS -BIOS = CCP+0x1600 ; BASE OF BIOS -CDISK = 4 ; CURRENT DISK NUMBER 0=A,...,15=P -IOBYTE = 3 ; I/O DEFINITION BYTE. - -END = 0x0FF -CR = 0x0D -LF = 0x0A - -; TEST PROTOTYPE SPECIFIC HARDWARE IO PORT ADDRESSES AND MEMORY LOCATIONS - -UART = 0x68 ; BASE IO ADDRESS OF UART -MPCL_RAM = 0x78 ; BASE IO ADDRESS OF RAM MEMORY PAGER CONFIGURATION LATCH -MPCL_ROM = 0x7C ; BASE IO ADDRESS OF ROM MEMORY PAGER CONFIGURATION LATCH - -ROMSTART_CPM= 0x00A00 ; WHERE THE CCP+BDOS+BIOS IS STORED IN ROM -RAMTARG_CPM= 0x0D000 ; WHERE THE CCP+BDOS+BIOS STARTS IN RAM (ENTRY POINT) -MOVSIZ_CPM= 0x02BFF ; CCP, BDOS -CCPSIZ_CPM= 0x00800 ; CCP 0800h BYTES IN LENGTH - -; IDE REGISTER IO PORT ; FUNCTION -IDELO = 0x20 ; DATA PORT (LOW BYTE) -IDEERR = 0x21 ; READ: ERROR REGISTER; WRITE: PRECOMP -IDESECTC = 0x22 ; SECTOR COUNT -IDESECTN = 0x23 ; SECTOR NUMBER -IDECYLLO = 0x24 ; CYLINDER LOW -IDECYLHI = 0x25 ; CYLINDER HIGH -IDEHEAD = 0x26 ; DRIVE/HEAD -IDESTTS = 0x27 ; READ: STATUS; WRITE: COMMAND -IDEHI = 0x28 ; DATA PORT (HIGH BYTE) -IDECTRL = 0x2E ; READ: ALTERNATIVE STATUS; WRITE; DEVICE CONTROL -IDEADDR = 0x2F ; DRIVE ADDRESS (READ ONLY) -FMSR = 0x36 ; ADDRESS OF MAIN STATUS REGISTER -FDATA = 0x37 ; FLOPPY DATA REGISTER -FLATCH = 0x3A ; FLOPPY CONFIGURATION LATCH -FDMA = 0x3C ; PSEUDO DMA ADDRESS -; -; FDC CONFIGURATION LATCH OUTPUT BIT PATTERNS -MOTOR = 0b00000000 ; BIT PATTERN IN LATCH FOR MOTOR CONTROL (ON) -TERMCN = 0b00000001 ; BIT PATTERN IN LATCH TO WRITE A TC STROBE -RESETL = 0b00000010 ; BIT PATTERN IN LATCH TO RESET ALL BITS -MINI = 0b00000100 ; BIT PATTERN IN LATCH TO SET MINI MODE FDC9229 LOW DENS=1, HIGH DENS=0 -PRECOMP = 0b00100000 ; BIT PATTERN IN LATCH TO SET WRITE PRECOMP 125 NS: -FDDENSITY = 0b01000000 ; BIT PATTERN IN LATCH TO FLOPPY LOW DENSITY (HIGH IS 0) -FDREADY = 0b10000000 ; BIT PATTERN IN LATCH TO FLOPPY READY (P-34): -; -; PIO 82C55 I/O IS DECODED TO PORT 60-67 -PORTA = 0x60 ; PORT A -PORTB = 0x61 ; PORT B -PORTC = 0x62 ; PORT C -PIOCONT = 0x63 ; PIO CONTROL PORT - - -;dwg; .ORG BIOS - -;__________________________________________________________________________________________________ -; -; CP/M JUMP VECTOR TABLE FOR INDIVIDUAL SUBROUTINES -;__________________________________________________________________________________________________ -; - JP BOOT ; COLD START -WBOOTE: JP WBOOT ; WARM START - JP CONST ; CONSOLE STATUS - JP CONIN ; CONSOLE CHARACTER IN - JP CONOUT ; CONSOLE CHARACTER OUT - JP LIST ; LIST CHARACTER OUT (NULL ROUTINE) - JP PUNCH ; PUNCH CHARACTER OUT (NULL ROUTINE) - JP READER ; READER CHARACTER OUT (NULL ROUTINE) - JP HOME ; MOVE HEAD TO HOME POSITION - JP SELDSK ; SELECT DISK - JP SETTRK ; SET TRACK NUMBER - JP SETSEC ; SET SECTOR NUMBER - JP SETDMA ; SET DMA ADDRESS - JP READ ; READ DISK - JP WRITE ; WRITE DISK - JP LISTST ; RETURN LIST STATUS (NULL ROUTINE) - JP SECTRN ; SECTOR TRANSLATE - -;__________________________________________________________________________________________________ -; -; FIXED DATA TABLES FOR ALL DRIVES -; 0= FLOPPY DISK OR RAM DISK, 1=RAM DISK, 2=IDE, 3=ATAPI OR RAM DISK, 4=HDPART4 -; 5= 1MB ROM DISK,6=32K ROM DISK -; -; NOTE: The RAM disk area is used as a substitute if the Floppy and/or ZIP drives are not enabled -; in the sustem. This RAM disk is the same "disk" as drive B. -; -;__________________________________________________________________________________________________ - -; DISK PARAMETER HEADER FOR DISK 00 -DPBASE: - .DW 0000,0000 - .DW 0000,0000 - .DW DIRBF,DPBLK1 - .DW CHK01,ALL01 - -; DISK PARAMETER HEADER FOR DISK 01 -.IF CONDUSEFLOPPY - .IF COND144FLOPPY - .DW 0000,0000 - .DW 0000,0000 - .DW DIRBF,DPBLK7 ; FOR 1.44M FLOPPIES - .DW CHK07,ALL07 - .ELSE - .DW 0000,0000 - .DW 0000,0000 - .DW DIRBF,DPBLK0 - .DW CHK00,ALL00 - .ENDIF -.ELSE - .DW 0000,0000 - .DW 0000,0000 - .DW DIRBF,DPBLK1 - .DW CHK01,ALL01 -.ENDIF -; DISK PARAMETER HEADER FOR DISK 02 - .DW 0000,0000 - .DW 0000,0000 - .DW DIRBF,DPBLK2 - .DW CHK02,ALL02 - - .IF CONDUSEATAPI -; DISK PARAMETER HEADER FOR DISK 03 - .DW 0000,0000 - .DW 0000,0000 - .DW DIRBF,DPBLK3 - .DW CHK03,ALL03 - .ELSE - .DW 0000,0000 - .DW 0000,0000 - .DW DIRBF,DPBLK1 - .DW CHK01,ALL01 - .ENDIF - -; DISK PARAMETER HEADER FOR DISK 04 - .DW 0000,0000 - .DW 0000,0000 - .DW DIRBF,DPBLK4 - .DW CHK04,ALL04 - -; DISK PARAMETER HEADER FOR DISK 05 - .DW 0000,0000 - .DW 0000,0000 - .DW DIRBF,DPBLK5 - .DW CHK05,ALL05 - -; DISK PARAMETER HEADER FOR DISK 06 - .DW 0000,0000 - .DW 0000,0000 - .DW DIRBF,DPBLK6 - .DW CHK06,ALL06 -; - -DPBLK0: ; DISK PARAMETER BLOCK (FLOPPY DISK 720KB) -SPT_0: .DW 36 ; 36 SECTORS OF 128 BYTES PER 4.5K TRACK -BSH_0: .DB 4 ; BLOCK SHIFT FACTOR (SIZE OF ALLOCATION BLOCK) -BLM_0: .DB 15 ; PART OF THE ALLOCATION BLOCK SIZE MATH -EXM_0: .DB 0 ; DEFINES SIZE OF EXTENT (DIRECTORY INFO) -DSM_0: .DW 350 ; BLOCKSIZE [2048] * NUMBER OF BLOCKS + 1 = DRIVE SIZE -DRM_0: .DW 127 ; NUMBER OF DIRECTORY ENTRIES -AL0_0: .DB 0b11000000 ; BIT MAP OF SPACE ALLOCATED TO DIRECTORY -AL1_0: .DB 0b00000000 ; DIRECTORY CAN HAVE UP TO 16 BLOCKS ALLOCATED -CKS_0: .DW 32 ; SIZE OF DIRECTORY CHECK [0 IF NON REMOVEABLE] -OFF_0: .DW 4 ; FIRST 4 TRACKS TRACKS RESERVED (18K FOR SYSTEM) - ; -DPBLK1: ; DISK PARAMETER BLOCK (RAMDISK 512K, 448K USABLE) -SPT_1: .DW 256 ; 256 SECTORS OF 128 BYTES PER 32K TRACK -BSH_1: .DB 4 ; BLOCK SHIFT FACTOR (SIZE OF ALLOCATION BLOCK) -BLM_1: .DB 15 ; PART OF THE ALLOCATION BLOCK SIZE MATH -EXM_1: .DB 1 ; DEFINES SIZE OF EXTENT (DIRECTORY INFO) -DSM_1: .DW 225 ; BLOCKSIZE [2048] * NUMBER OF BLOCKS + 1 = DRIVE SIZE -DRM_1: .DW 255 ; NUMBER OF DIRECTORY ENTRIES -AL0_1: .DB 0b11110000 ; BIT MAP OF SPACE ALLOCATED TO DIRECTORY -AL1_1: .DB 0b00000000 ; DIRECTORY CAN HAVE UP TO 16 BLOCKS ALLOCATED -CKS_1: .DW 0 ; SIZE OF DIRECTORY CHECK [0 IF NON REMOVEABLE] -OFF_1: .DW 1 ; 1 TRACK RESERVED [FIRST 32K OF RAM] - ; -DPBLK2: ; DISK PARAMETER BLOCK (IDE HARD DISK 8MB) -SPT_2: .DW 256 ; 256 SECTORS OF 128 BYTES PER 32K TRACK -BSH_2: .DB 5 ; BLOCK SHIFT FACTOR (SIZE OF ALLOCATION BLOCK) -BLM_2: .DB 31 ; PART OF THE ALLOCATION BLOCK SIZE MATH -EXM_2: .DB 1 ; DEFINES SIZE OF EXTENT (DIRECTORY INFO) -DSM_2: .DW 2017 ; BLOCKSIZE [4096] * NUMBER OF BLOCKS + 1 = DRIVE SIZE -DRM_2: .DW 511 ; NUMBER OF DIRECTORY ENTRIES -AL0_2: .DB 0b11110000 ; BIT MAP OF SPACE ALLOCATED TO DIRECTORY -AL1_2: .DB 0b00000000 ; DIRECTORY CAN HAVE UP TO 16 BLOCKS ALLOCATED -CKS_2: .DW 0 ; SIZE OF DIRECTORY CHECK [0 IF NON REMOVEABLE] -OFF_2: .DW 0x03F1 ; TRACKS (32K) RESERVED FOR SYSTEM AND OTHER PARTITIONS - ; -DPBLK3: ; DISK PARAMETER BLOCK (ATAPI DRIVE 8MB) -SPT_3: .DW 256 ; 256 SECTORS OF 128 BYTES PER 32K TRACK -BSH_3: .DB 5 ; BLOCK SHIFT FACTOR (SIZE OF ALLOCATION BLOCK) -BLM_3: .DB 31 ; PART OF THE ALLOCATION BLOCK SIZE MATH -EXM_3: .DB 1 ; DEFINES SIZE OF EXTENT (DIRECTORY INFO) -DSM_3: .DW 2017 ; BLOCKSIZE [4096] * NUMBER OF BLOCKS + 1 = DRIVE SIZE -DRM_3: .DW 511 ; NUMBER OF DIRECTORY ENTRIES -AL0_3: .DB 0b11110000 ; BIT MAP OF SPACE ALLOCATED TO DIRECTORY -AL1_3: .DB 0b00000000 ; DIRECTORY CAN HAVE UP TO 16 BLOCKS ALLOCATED -CKS_3: .DW 0 ; SIZE OF DIRECTORY CHECK [0 IF NON REMOVEABLE] -OFF_3: .DW 1 ; 1 TRACK (32K) RESERVED FOR SYSTEM - ; -DPBLK4: ; DISK PARAMETER BLOCK (IDE HARD DISK 1024K) -SPT_4: .DW 256 ; 256 SECTORS OF 128 BYTES PER 32K TRACK -BSH_4: .DB 4 ; BLOCK SHIFT FACTOR (SIZE OF ALLOCATION BLOCK) -BLM_4: .DB 15 ; PART OF THE ALLOCATION BLOCK SIZE MATH -EXM_4: .DB 1 ; DEFINES SIZE OF EXTENT (DIRECTORY INFO) -DSM_4: .DW 497 ; BLOCKSIZE [2048] * NUMBER OF BLOCKS + 1 = DRIVE SIZE -DRM_4: .DW 255 ; NUMBER OF DIRECTORY ENTRIES -AL0_4: .DB 0b11110000 ; BIT MAP OF SPACE ALLOCATED TO DIRECTORY -AL1_4: .DB 0b00000000 ; DIRECTORY CAN HAVE UP TO 16 BLOCKS ALLOCATED -CKS_4: .DW 0 ; SIZE OF DIRECTORY CHECK [0 IF NON REMOVEABLE] -OFF_4: .DW 1 ; 1 TRACK RESERVED [FIRST 32K OF PARTITION] - ; -DPBLK5: ; DISK PARAMETER BLOCK (ROMDISK 1MB) -SPT_5: .DW 256 ; 256 SECTORS OF 128 BYTES PER 32K TRACK -BSH_5: .DB 4 ; BLOCK SHIFT FACTOR (SIZE OF ALLOCATION BLOCK) -BLM_5: .DB 15 ; PART OF THE ALLOCATION BLOCK SIZE MATH -EXM_5: .DB 0 ; DEFINES SIZE OF EXTENT (DIRECTORY INFO) -DSM_5: .DW 511 ; BLOCKSIZE [2048] * NUMBER OF BLOCKS +1 =DRIVE SIZE -DRM_5: .DW 255 ; NUMBER OF DIRECTORY ENTRIES -AL0_5: .DB 0b11110000 ; BIT MAP OF SPACE ALLOCATED TO DIRECTORY -AL1_5: .DB 0b00000000 ; DIRECTORY CAN HAVE UP TO 16 BLOCKS ALLOCATED -CKS_5: .DW 0 ; SIZE OF DIRECTORY CHECK [0 IF NON REMOVEABLE] -OFF_5: .DW 1 ; 1 TRACK RESERVED [FIRST 32K OF ROM] - ; -DPBLK6: ; DISK PARAMETER BLOCK (ROMDISK 32KB) -SPT_6: .DW 16 ; 16 SECTORS OF 128 BYTES PER 2K TRACK -BSH_6: .DB 3 ; BLOCK SHIFT FACTOR (SIZE OF ALLOCATION BLOCK) -BLM_6: .DB 7 ; PART OF THE ALLOCATION BLOCK SIZE MATH -EXM_6: .DB 1 ; DEFINES SIZE OF EXTENT (DIRECTORY INFO) -DSM_6: .DW 31 ; BLOCKSIZE [1024] * NUMBER OF BLOCKS + 1 = DRIVE SIZE -DRM_6: .DW 31 ; NUMBER OF DIRECTORY ENTRIES -AL0_6: .DB 0b10000000 ; BIT MAP OF SPACE ALLOCATED TO DIRECTORY -AL1_6: .DB 0b00000000 ; DIRECTORY CAN HAVE UP TO 16 BLOCKS ALLOCATED -CKS_6: .DW 0 ; SIZE OF DIRECTORY CHECK [0 IF NON REMOVEABLE] -OFF_6: .DW 10 ; FIRST 10 TRACKS TRACKS RESERVED (20K FOR SYSTEM) - ; SYSTEM IS ROM LOADER, CCP, BDOS, CBIOS, AND MONITOR -DPBLK7: ; DISK PARAMETER BLOCK FLOPPY 1.44M -SPT_7: .DW 72 ; 16 SECTORS OF 128 BYTES PER 2K TRACK -BSH_7: .DB 4 ; BLOCK SHIFT FACTOR (SIZE OF ALLOCATION BLOCK) -BLM_7: .DB 15 ; PART OF THE ALLOCATION BLOCK SIZE MATH -EXM_7: .DB 0 ; DEFINES SIZE OF EXTENT (DIRECTORY INFO) -DSM_7: .DW 710 ; BLOCKSIZE [1024] * NUMBER OF BLOCKS + 1 = DRIVE SIZE -DRM_7: .DW 255 ; NUMBER OF DIRECTORY ENTRIES -AL0_7: .DB 0b11110000 ; BIT MAP OF SPACE ALLOCATED TO DIRECTORY -AL1_7: .DB 0b00000000 ; DIRECTORY CAN HAVE UP TO 16 BLOCKS ALLOCATED - -CKS_7: .DW 32 ; SIZE OF DIRECTORY CHECK [0 IF NON REMOVEABLE] -OFF_7: .DW 2 ; FIRST 10 TRACKS TRACKS RESERVED (20K FOR SYSTEM) - ; SYSTEM IS ROM LOADER, CCP, BDOS, CBIOS, AND MONITOR - ; - ; IMPORTANT NOTE: TRACKS 00h - 0AH OF 2K BYTES - ; EACH ARE MARKED WITH THE OFF_6 SET TO 5 AS - ; SYSTEM TRACKS USABLE ROM DRIVE SPACE - ; STARTING AFTER THE TENTH TRACK (IE, TRACK 0AH) - ; MOST LIKELY FIX TO THIS IS PLACING A DUMMY - ; FIRST 20K ROM CONTAINS THE ROM LOADER, MONITOR, - ; CCP, BDOS, BIOS, ETC (10 TRACKS * 2K EACH) -;__________________________________________________________________________________________________ -; -; END OF FIXED CP/M TABLES -; -; INDIVIDUAL SUBROUTINES TO PERFORM EACH FUNCTION -;__________________________________________________________________________________________________ - - -;___BOOT___________________________________________________________________________________________ -BOOT: ; SIMPLEST CASE IS TO JUST PERFORM PARAMETER INITIALIZATION - ; - LD A,#0x80 ; LOAD VALUE TO SWITCH OUT ROM - OUT (MPCL_ROM),A ; SWITCH OUT ROM, BRING IN LOWER 32K RAM PAGE - ; - ; - LD A,#0b10000001 ; SWITCH IN FIRST 32K LOWER PAGE (FIRST TRACK) - OUT (MPCL_RAM),A ; - ; FORMATTING THE RAM IS SIMPLE AS CLEARING THE DIRECTORY AREA - ; TO A VALUE OF E5H (THE FIRST 8K OF TRACK 1 OR THE RAMDISK) - LD HL,#0000 ; STARTING MEMORY ADDRESS OF TRACK 1, SECTOR 0 IN HL - LD BC,#0x1FFF ; 8K OF DIRECTORY SECTORS RESERVED (LENGTH IN BC) - LD A,#0x0E5 ; INITIALIZING VALUE IN A - LD E,L ; - LD D,H ; - INC DE ; - LD (HL),A ; - LDIR ; - ; - LD A,#0x80 ; LOAD VALUE TO SWITCH OUT ROM - OUT (MPCL_ROM),A ; SWITCH OUT ROM, BRING IN LOWER 32K RAM PAGE - ; - LD A,#0 ; ENSURE LOWEST RAM PAGE SELECTED - OUT (MPCL_RAM),A ; BRING IN LOWEST 32K RAM PAGE - ; - XOR A ; ZERO IN THE ACCUM - LD (IOBYTE),A ; CLEAR THE IOBYTE - LD (CDISK),A ; SELECT DISK 0 - ; - CALL IDE_SOFT_RESET ; RESET THE IDE HARD DISK - ; - ; - JP GOCPM ; INITIALIZE AND GO TO CP/M - ; -; -;___WBOOT__________________________________________________________________________________________ -WBOOT: ; SIMPLEST CASE IS TO READ THE DISK UNTIL ALL SECTORS LOADED - ; WITH A ROMDISK WE SELECT THE ROM AND THE CORRECT PAGE [0] - ; THEN COPY THE CP/M IMAGE (CCP, BDOS, BIOS, MONITOR) TO HIGH RAM - ; LOAD ADDRESS - ; FOR Z80 IT LOOKS LIKE THIS . USING 8080 NEMONICS - ; - DI ; DISABLE INTERRUPT - LD SP,#0x80 ; USE SPACE BELOW BUFFER FOR STACK - IM 1 ; SET INTERRUPT MODE 1 - ; - XOR A ; CHEAP ZERO IN ACC - OUT (MPCL_ROM),A ; SEND 0 TO ROM MAP PORT (SWITCH IN LOWER 32K ROM PAGE) - ; - XOR A ; CHEAP ZERO IN ACC - OUT (MPCL_RAM),A ; SEND 0 TO RAM MAP PORT (SELECT LOWEST RAM PAGE) - ; - LD HL,#ROMSTART_CPM ; WHERE IN ROM CP/M IS STORED (FIRST BYTE) - LD DE,#RAMTARG_CPM ; WHERE IN RAM TO MOVE MONITOR TO (FIRST BYTE) - LD BC,#CCPSIZ_CPM ; NUMBER OF BYTES TO MOVE FROM ROM TO RAM - LDIR ; - ; - ; -;;;;; EI ; ENABLE INTERRUPTS - LD A,#0x80 ; LOAD VALUE TO SWITCH OUT ROM - OUT (MPCL_ROM),A ; SWITCH OUT ROM, BRING IN LOWER 32K RAM PAGE - ; - XOR A ; CHEAP ZERO IN ACC - OUT (MPCL_RAM),A ; SEND 0 TO RAM MAP PORT (SELECT LOWEST RAM PAGE) - ; - CALL IDE_SOFT_RESET ; RESET THE IDE HARD DISK - ; - .IF CONDSUPERSUB ; - ; DO NOTHING FOR ORIGINAL CODE - .ELSE ; - ; CLEAR THE AUTOSUB BUFFER, DO ON A WARM BOOT - XOR A ; - LD (INBUFF+1),A ; SECOND BYTE IS ACTUAL LENGTH - .ENDIF ; - ; FALL THROUGH TO GOCPM ROUTINE -; -; END OF LOAD OPERATION, SET PARAMETERS AND GO TO CP/M -; -;___GOCPM__________________________________________________________________________________________ -GOCPM: - ; CPU RESET HANDLER - LD A,#0x0C3 ; C3 IS A JMP INSTRUCTION - LD (0),A ; FOR JMP TO WBOOT - LD HL,#WBOOTE ; WBOOT ENTRY POINT - LD (1),HL ; SET ADDRESS FIELD FOR JMP AT 0 - ; - ; CPU INTERRUPT HANDLER - LD A,#0x0C3 ; C3 IS A JMP INSTRUCTION - LD (0x0038),A ; FOR JMP TO WBOOT - LD HL,#WBOOTE ; WBOOT ENTRY POINT - LD (1),HL ; SET ADDRESS FIELD FOR JMP AT 0 - ; - LD (5),A ; FOR JMP TO BDOS - LD HL,#BDOS ; BDOS ENTRY POINT - LD (6),HL ; ADDRESS FIELD OF JUMP AT 5 TO BDOS - ; - LD BC,#0x80 ; DEFAULT DMA ADDRESS IS 80H - CALL SETDMA ; - ; - .IF CONDUSEFLOPPY ; - CALL SETUPDRIVE ; SETUP FLOPPY PARAMETERS - .ENDIF ; - ; - .IF CONDUSEVDU ; - DI ; DISABLE INTERRUPTS - LD A,#0x1F ; SET HIGH ROM PAGE - OUT (MPCL_ROM),A ; SEND TO ROM PORT MAPPER - LD HL,#0 ; - ADD HL,SP ; GET STACK POINTER INTO HL - LD (PARKSTACK),HL ; SAVE STACK POINTER - LD SP,#FLOPPYSTACK ; - CALL VDU_INIT ; - LD SP,(PARKSTACK) ; RESTORE STACK - LD A,#0x80 ; LOAD VALUE TO SWITCH OUT ROM - OUT (MPCL_ROM),A ; - LD A,#0 ; CHOOSE HIGHEST RAM PAGE - OUT (MPCL_RAM),A ; SEND 19H TO RAM MAP PORT (SELECT HIGHEST RAM PAGE) -;;;;; EI ; ENABLE INTERRUPTS - .ENDIF ; - LD HL,#TXT_STARTUP_MSG ; PRINT STARTUP MESSAGE - CALL PRTMSG ; - ; - LD A,(CDISK) ; GET CURRENT DISK NUMBER - LD C,A ; SEND TO THE CCP - JP CCP ; GO TO CP/M FOR FURTHER PROCESSING - ; -;__________________________________________________________________________________________________ -; -; ** CONSOLE & PRINTER I/O -- VDU CARD DRIVER INTERFACE -; -;__________________________________________________________________________________________________ - .IF CONDUSEVDU -CONST: - PUSH HL ; STORE HL - DI ; DISABLE INTERRUPTS - LD A,#1FH ; SET HIGH ROM PAGE - OUT (MPCL_ROM),A ; SEND TO ROM PORT MAPPER - LD HL,#0 ; - ADD HL,SP ; GET STACK POINTER INTO HL - LD (PARKSTACK),HL ; SAVE STACK POINTER - LD SP,#FLOPPYSTACK ; - CALL IS_KBHIT ; CHECK FOR KB HIT - LD C,A ; STORE RESULT - LD SP,(PARKSTACK) ; RESTORE STACK - LD A,#0x80 ; LOAD VALUE TO SWITCH OUT ROM - OUT (MPCL_ROM),A ; - LD A,#0 ; CHOOSE HIGHEST RAM PAGE - OUT (MPCL_RAM),A ; SEND 19H TO RAM MAP PORT (SELECT HIGHEST RAM PAGE) - LD A,C ; RESTORE RESULT -;;;;; EI ; ENABLE INTERRUPTS - POP HL ; RESTORE HL - RET - -CONIN: - PUSH HL ; STORE HL - DI ; DISABLE INTERRUPTS - LD A,#0x1F ; SET HIGH ROM PAGE - OUT (MPCL_ROM),A ; SEND TO ROM PORT MAPPER - LD HL,#0 ; - ADD HL,SP ; GET STACK POINTER INTO HL - LD (PARKSTACK),HL ; SAVE STACK POINTER - LD SP,#FLOPPYSTACK ; - CALL GET_KEY ; GET KEY FROM KEYBOARD - LD C,A ; STORE RESULT - LD SP,(PARKSTACK) ; RESTORE STACK - LD A,#0x80 ; LOAD VALUE TO SWITCH OUT ROM - OUT (MPCL_ROM),A ; - LD A,#0x00 ; CHOOSE HIGHEST RAM PAGE - OUT (MPCL_RAM),A ; SEND 19H TO RAM MAP PORT (SELECT HIGHEST RAM PAGE) - LD A,C ; RESTORE RESULT -;;;;; EI ; ENABLE INTERRUPTS - POP HL ; RESTORE HL - RET - -CONOUT: - PUSH HL ; STORE HL - DI ; DISABLE INTERRUPTS - LD A,#0x1F ; SET HIGH ROM PAGE - OUT (MPCL_ROM),A ; SEND TO ROM PORT MAPPER - LD HL,#0 ; - ADD HL,SP ; GET STACK POINTER INTO HL - LD (PARKSTACK),HL ; SAVE STACK POINTER - LD SP,#FLOPPYSTACK ; - LD A,C ; RESTORE CHARACTER - CALL CHARIN ; DISPLAY CHARACTER - LD SP,(PARKSTACK) ; RESTORE STACK - LD A,#0x80 ; LOAD VALUE TO SWITCH OUT ROM - OUT (MPCL_ROM),A ; - LD A,#0x00 ; CHOOSE HIGHEST RAM PAGE - OUT (MPCL_RAM),A ; SEND 19H TO RAM MAP PORT (SELECT HIGHEST RAM PAGE) -;;;;; EI ; ENABLE INTERRUPTS - POP HL ; RESTORE HL - RET -LIST: - PUSH HL ; STORE HL - DI ; DISABLE INTERRUPTS - LD A,#0x1F ; SET HIGH ROM PAGE - OUT (MPCL_ROM),A ; SEND TO ROM PORT MAPPER - LD HL,#0 ; - ADD HL,SP ; GET STACK POINTER INTO HL - LD (PARKSTACK),HL ; SAVE STACK POINTER - LD SP,#FLOPPYSTACK ; - LD A,C ; RESTORE CHARACTER - CALL PR_OUTCHAR ; - LD SP,(PARKSTACK) ; RESTORE STACK - LD A,#0x80 ; LOAD VALUE TO SWITCH OUT ROM - OUT (MPCL_ROM),A ; - LD A,#0x00 ; CHOOSE HIGHEST RAM PAGE - OUT (MPCL_RAM),A ; SEND 19H TO RAM MAP PORT (SELECT HIGHEST RAM PAGE) -;;;;; EI ; ENABLE INTERRUPTS - POP HL ; RESTORE HL - RET - -;__________________________________________________________________________________________________ -; -; ** CONSOLE I/O -- ON-BOARD 16550 SERIAL INTERFACE -; -;__________________________________________________________________________________________________ - .ELSE -CONST: ; CONSOLE STATUS, RETURN 0FFH IF CHARACTER READY, 00H IF NOT - IN A,(UART + 5) ; READ LINE STATUS REGISTER (UART5 = 068h + $05) - AND #0x01 ; TEST IF DATA IN RECEIVE BUFFER - ; IS THERE A CHAR READY? 0=NO, 1=YES - JP Z,NOT_READY ; - LD A,#0x0FF ; YES, PUT 0FFh IN A AND RETURN -NOT_READY: ; - ; NO, LEAVE 000h IN A AND RETURN - RET ; -CONIN: ; CONSOLE CHARACTER INTO REGISTER A - ; - CALL CONST ; IS A CHAR READY TO BE READ FROM UART? - CP #0 ; - JP Z,CONIN ; NO? TRY AGAIN - IN A,(UART) ; YES? READ THE CHAR FROM THE UART (UART0 = 068h + $00) - ; REGISTER AND PASS BACK TO USER - RET ; - ; -CONOUT: ; CONSOLE CHARACTER OUTPUT FROM REGISTER C - IN A,(UART + 5) ; READ LINE STATUS REGISTER - AND #0x20 ; TEST IF UART IS READY TO SEND - JP Z,CONOUT ; IF NOT REPEAT - ; - LD A,C ; GET TO ACCUMULATOR - OUT (UART),A ; THEN WRITE THE CHAR TO UART (UART0 = 068h + $00) - RET ; - ; -LIST: ;LIST CHARACTER FROM REGISTER C - LD A,C ;CHARACTER TO REGISTER A - RET ;NULL SUBROUTINE - .ENDIF - ; -LISTST: ;RETURN LIST STATUS (0 IF NOT READY, 1 IF READY) - XOR A ;0 IS ALWAYS OK TO RETURN - RET ; - ; - ; -;__________________________________________________________________________________________________ -; -; ** PUNCH & READER I/O -- STUB -; -;__________________________________________________________________________________________________ -PUNCH: ;PUNCH CHARACTER FROM REGISTER C - LD A,C ;CHARACTER TO REGISTER A - RET ;NULL SUBROUTINE - ; -READER: ;READ CHARACTER INTO REGISTER A FROM READER DEVICE - LD A,C ;CHARACTER TO REGISTER A - RET - - -;__________________________________________________________________________________________________ -; -; ** DISK STORAGE I/O -; -;__________________________________________________________________________________________________ -; -; SELECT DISK GIVEN BY REGISTER C -;__________________________________________________________________________________________________ - -SELDSK: LD HL,#0x0000 ; ERROR RETURN CODE - LD A,C ; - .IF CONDABONLY ; - CP #7 ; MUST BE BETWEEN 0 AND 6 - .ELSE ; - CP #2 ; IF NO IDE THEN ONLY DRIVE A AND B FOR THE MINI N8VEM SO 0 OR 1 ONLY - .ENDIF ; - RET NC ; RETURN IF OUT OF RANGE - LD (DISKNO),A ; - ; DISK NUMBER IS IN THE PROPER RANGE - ; COMPUTE PROPER DISK PARAMETER HEADER ADDRESS - LD L,A ; L=DISK NUMBER 0,1,2,3,4 - LD H,#0 ; HIGH ORDER ZERO - ADD HL,HL ; *2 - ADD HL,HL ; *4 - ADD HL,HL ; *8 - ADD HL,HL ; *16 (SIZE OF EACH HEADER) - LD DE,#DPBASE ; - ADD HL,DE ; HL= DPBASE(DISKNO*16) - RET -;__________________________________________________________________________________________________ -HOME: ; MOVE TO THE TRACK 00 POSITION OF CURRENT DRIVE - ; TRANSLATE THIS CALL INTO A SETTRK CALL WITH PARAMETER 00 - LD BC,#0 ; SELECT TRACK 0000 -;__________________________________________________________________________________________________ -SETTRK: ; SET TRACK GIVEN BY REGISTER BC - LD H,B ; - LD L,C ; - LD (TRACK),HL ; - RET -;__________________________________________________________________________________________________ -SETSEC: ; SET SECTOR GIVEN BY REGISTER BC - LD H,B ; - LD L,C ; - LD (SECTOR),HL ; - RET ; -;__________________________________________________________________________________________________ -; -; TRANSLATE THE SECTOR GIVEN BY BC USING THE -; TRANSLATE TABLE GIVEN BY DE -; ONLY USED FOR FLOPPIES! FOR ROMDISK/RAMDISK/IDE/ATAPI IT'S 1:1 -; DO THE NEXT ROUTINE IS A NULL (RETURNS THE SAME) -;__________________________________________________________________________________________________ -SECTRN: - LD H,B ; - LD L,C ; - RET ; -;__________________________________________________________________________________________________ -SETDMA: ; SET DMA ADDRESS GIVEN BY REGISTERS B AND C - LD L,C ; LOW ORDER ADDRESS - LD H,B ; HIGH ORDER ADDRESS - LD (DMAAD),HL ; SAVE THE ADDRESS - RET -;________________________________________________________________________________________________________ -; DISK DRIVERS . -; -; DRIVER NEEDS TO DO SEVERAL THINGS FOR ROM AND RAM DISKS -; - INTERRUPTS ARE NOT ALLOWED DURING LOW RAM/ROM ACCESS (DISABLE!) -; -TRANSLATE TRACK AND SECTOR INTO A POINTER TO WHERE THE 128 BYTE -; SECTOR BEGINS IN THE RAM/ROM -; -TRANSLATE THE DRIVE INTO A RAM/ROM SELECT, COMBINE WITH TRACK ADDRESS -; AND SEND TO THE MAP PORT -; -COPY 128 BYTE FROM OR TO THE ROM/RAMDISK AND MEMORY POINTED TO BY THE DMA -; ADDRESS PREVIOUSLY STORED -; -RESTORE MAP PORT TO PRIOR CONDITION BEFOR READ/WRITE -; -; - FIRST TRICK IS THAT WE MADE SECTORS 256 AS 256*128=32768 SO WE COPY -; THE LOW SECTOR ADDRESS TO THE LOW BYTE OF THE HL REGISTER AND THEN -; MULTIPLY BY 128 THIS RESULTS IN THE STARTING ADDRESS IN THE RAM OR ROM -; (0000 -> 7F80H) 32K PAGE -; -; - TRICK TWO IS THE TRACK ADDRESS EQUALS THE 32K PAGE ADDRESS AND IS A -; DIRECT SELECT THAT CAN BE COPIED TO THE MAP PORT D0 THROUGH D5 D7 -; SELECTS THE DRIVE (ROM OR RAM) -; THAT MEANS THE LOW BYTE OF TRACK CONTAINS THE D0-D5 VALUE AND -; DISKNO HAS THE DRIVE SELECTED WE FIRST COPY DISKNO TO ACC -; AND RIGHTSHIFT IT TO PLACE THAT IN BIT 7, WE THEN ADD THE LOW BYTE OF -; TRACK TO ACC AND THEN SEND THAT TO THE MAP PORT -; -; NOTE 1: A WRITE TO ROM SHOULD BE FLAGGED AS AN ERROR -; NOTE 2: RAM MUST START AS A "FORMATTED DISK" IF BATTERY BACKED UP -; IT'S A DO ONCE AT COLD COLD START IF NOT BATTERY BACKED U -; IT WILL HAVE TO BE DONE EVERY TIME THE SYSTEM IS POWERED -; FORMATTING THE RAM IS SIMPLE AS CLEARING THE DIRECTORY AREA -; TO A VALUE OF E5H (THE FIRST 8K OF TRACK 1 OR THE RAMDISK) -; IT COULD BE DONE AS A SIMPLE UTILITY PROGRAM STORED IN ROMD -; OR ANYTIME COLBOOT IS CALLED(LESS DESIREABLE) -; -; -WE NOW CAN COPY TO OR FROM AS CORRECT FOR THE DEVICE 128 BYTES (SECTOR) -; TO OR FROM THE DMA ADDRESS ALMOST! SINCE ROM OR RAM IS BEING PAGED -; WE HAVE TO COPY ANYTHING DETINED FOR BELOW 8000H TO A TEMP BUFFER THEN -; HANDLE THE PAGING -; -; -; - LAST STEP IS TO RESTORE THE MAP PORT TO POINT TO THE RAM (TRACK 0) SO T -; MEMORY MAP IS ALL RAM AGAIN AND NOT POINTING INTO THE DATA AREAS OR THE -; SINCE THE RAM 0TH PAGE IS NOMINALLY THE LOW 32K OF RAM IN THE SYSTEM WE -; SEND A SIMPLE MVI A,80H ; OUT MPCL_ROM ; MVI A,00H ; OUT MPCL_RAM -; -; - THE READ OR WRITE OPERATION IS DONE -; -; READ DISK -; USES DE,DL, BC, ACC FLAGS -; Z80 COULD USE BLOCK MOVE [LDIR] BUT WRITTEN IN 8080 -;________________________________________________________________________________________________________ - -;__READ__________________________________________________________________________________________________ -; -; PERFORM CP/M SECTOR READ -;________________________________________________________________________________________________________ -READ: - DI ; DISABLE INTERRUPTS - LD A,(DISKNO) ; GET DRIVE - CP #0x01 ; "B" - .IF CONDUSEFLOPPY - JP Z,READ_FLPY_DSK ; READ FLOPPY - .ELSE - JP Z,READ_RAM_DISK ; READ FROM 448K RAM DISK - .ENDIF - CP #0 ; "B" - JP Z,READ_RAM_DISK ; READ FROM 448K RAM DISK - CP #2 ; "C" - JP Z,READ_IDE ; READ FROM 8 MB IDE HARD DISK - CP #3 ; "D" - .IF CONDUSEATAPI - JP Z,READ_ATAPI ; READ FROM 8 MB ATAPI - .ELSE - JP Z,READ_RAM_DISK ; READ FROM 448K RAM DISK - .ENDIF - - CP #4 ; "E" - JP Z,READ_HDPART4 ; READ FROM 1 MB IDE HARD DISK, PARTITION 4 ** future use - CP #5 ; "F" - JP Z,READ_RAM_DISK ; READ FROM 1M ROM DISK (UTILIZES SAME - ; ROUTINES AS RAM_DISK - ; "G" - ; READ FROM 22K EEPROM DISK , SO FALL THROUGH - -;___READ_EEPROM_DISK_____________________________________________________________________________________ -; -; READ EEPROM DISK -;________________________________________________________________________________________________________ -READ_EEPROM_DISK: - ; - ; IF ROM, MAP TRACK/SECTOR TO VIRTUAL TRACK/SECTOR - ; HANDLE READING FROM ROM HERE - ; - ; PURPOSE OF THIS ROUTINE IS TO MAP 32K ROM PART - ; TRACK/SECTOR MAP (2K TRACK SIZE MADE OF 16 128 - ; BYTE SECTORS EACH) ONTO WHAT THE RAM/ROM SECTOR - ; READ ROUTINES ARE EXPECTING (32K TRACK SIZE MADE - ; OF 256 128 BYTE SECTORS EACH) THE ROUTINE - ; CONVERTS 4 BIT TRACK # AND 4 BIT SECTOR # - ; INTO A VIRTUAL 1 TRACK, 256 SECTOR ACCESS - LD HL,(TRACK) ; TRACK # IS UPPER 4 BITS OF SECTOR ADDRESS - ADD HL,HL ; SHIFT BITS LEFT 1 (*2) - ADD HL,HL ; SHIFT BITS LEFT 1 (*4) - ADD HL,HL ; SHIFT BITS LEFT 1 (*8) - ADD HL,HL ; SHIFT BITS LEFT 1 (*16) - LD B,H ; PUT UPPER 4 BITS OF SECTOR ADDRESS IN BC - LD C,L ; (B IS UPPER BYTE AND C IS LOWER BYTE) - ; BC NOW CONTAINS THE UPDATED TRACK # - LD HL,(SECTOR) ; SECTOR # IS LOWER 4 BITS OF SECTOR ADDRESS - ADD HL,BC ; VIRTUAL SECTOR = (UPDATED TRACK #) + SECTOR # - LD (PSECTOR),HL ; STORE VIRTUAL SECTOR # - ; NOW CONTINUE READING ROM WITH REGULAR RAM - ; SETUP FOR READ OF RAM OR ROM DISK - LD HL,(PSECTOR) ; - ADD HL,HL ; SHIFT BITS LEFT 1 (*2) - ADD HL,HL ; SHIFT BITS LEFT 1 (*4) - ADD HL,HL ; SHIFT BITS LEFT 1 (*8) - ADD HL,HL ; SHIFT BITS LEFT 1 (*16) - ADD HL,HL ; SHIFT BITS LEFT 1 (*32) - ADD HL,HL ; SHIFT BITS LEFT 1 (*64) - ADD HL,HL ; SHIFT BITS LEFT 1 (*128) - LD (SECST),HL ; SAVE SECTOR STARTING ADDRESS - ; SET PAGER WITH DRIVE (0) AND TRACK (0) - LD A,#0 ; SWITCH IN ROM PAGE - OUT (MPCL_ROM),A ; SEND TO PORT MAPPER - LD (PAGER),A ; SAVE COPY (JUST BECAUSE) - LD HL,#SECTOR_BUFFER ; LOAD HL WITH TEMP BUF ADDRESS - LD E,L ; - LD D,H ; GET IT INTO DE - LD HL,(SECST) ; GET ROM/RAM ADDRESS - CALL COPY_CPM_SECTOR ; - CALL RPAGE ; SET PAGE TO CP/M RAM - LD HL,(DMAAD) ; LOAD HL WITH DMA ADDRESS - LD E,L ; - LD D,H ; GET IT INTO DE - LD HL,#SECTOR_BUFFER ; GET ROM/RAM ADDRESS - CALL COPY_CPM_SECTOR ; - LD A,(DISKNO) ; STORE CURRENT DRIVE IN BUFFER - LD (CUDISK),A ; - LD A,#0 ; -;;;;; EI ; RE-ENABLE INTERRUPTS - RET -;___READ_RAM_DISK_________________________________________________________________________________________ -; -; READ RAM DISK -;________________________________________________________________________________________________________ -READ_RAM_DISK: ; - ; IF RAM, PROCEED WITH NORMAL TRACK/SECTOR READ - CALL SECPAGE ; SETUP FOR READ OF RAM OR ROM DISK - CALL PAGERB ; SET PAGER WITH DRIVE AND TRACK - LD HL,#SECTOR_BUFFER ; LOAD HL WITH TEMP BUF ADDRESS - LD E,L ; - LD D,H ; GET IT INTO DE - LD HL,(SECST) ; GET ROM/RAM ADDRESS - CALL COPY_CPM_SECTOR ; MOVE SECTOR TO SECTOR_BUFFER - CALL RPAGE ; SET PAGE TO CP/M RAM - LD HL,(DMAAD) ; LOAD HL WITH DMA ADDRESS ; - LD E,L ; - LD D,H ; GET IT INTO DE - LD HL,#SECTOR_BUFFER ; GET ROM/RAM ADDRESS - CALL COPY_CPM_SECTOR ; MOVE SECTOR FROM SECTOR_BUFFER TO DMA AREA - LD A,(DISKNO) ; STORE CURRENT DRIVE IN BUFFER - LD (CUDISK),A ; - LD A,#0 ; -;;;;; EI ; RE-ENABLE INTERRUPTS - RET - -;___TRFLSEC______________________________________________________________________________________________ -; -; TRANSLATE LOGICAL FLOPPY DISK SECTOR TO PHYSICAL SECTOR -; IN: TRACK,SECTOR -; OUT: PTRACK,PSECTOR,SECTOR_INDEX -;________________________________________________________________________________________________________ -TRFLSEC: - LD A,(TRACK) ; LOAD TRACK # (LOW BYTE) - AND #1 ; FILTER OUT HEAD - LD (HEAD),A ; STORE HEAD - LD A,(TRACK) ; SAVE TRACK IN A - SRL A ; REMOVE HEAD BIT - LD (PTRACK),A ; STORE IN TRACK - LD A,(SECTOR) ; LOAD SECTOR # (LOW BYTE) - LD (SECTOR_INDEX),A ; STORE SECTOR IN SECTOR INDEX - SRL A ; - SRL A ; DIVIDE BY 4 (FOR BLOCKING) - LD (PSECTOR),A ; STORE IN SECTOR - LD A,(SECTOR_INDEX) ; FILTER OUT UNWANTED BITS - AND #3 ; - LD (SECTOR_INDEX),A ; - RET - -;___DEBSEC_______________________________________________________________________________________________ -; -; DEBLOCK 512 BYTE SECTOR FOR CP/M -; -;________________________________________________________________________________________________________ -DEBSEC: - LD HL,(DMAAD) ; LOAD HL WITH DMA ADDRESS - LD D,H ; TRANSFER HL REGISTERS TO DE - LD E,L ; - PUSH DE ; STORE DE - ; COMPUTE STARTING ADDRESS OF CP/M SECTOR IN READ SECTOR BUFFER - LD HL,#SECTOR_BUFFER ; LOAD HL WITH SECTOR BUFFER ADDRESS - LD A,(SECTOR_INDEX) ; GET THE SECTOR INDEX (CP/M SECTOR OFFSET IN BUFFER) - RRCA ; MOVE BIT 0 TO BIT 7 - RRCA ; DO AGAIN - IN EFFECT MULTIPLY BY 4 - LD D,#0 ; PUT RESULT AS 16 VALUE IN DE, UPPER BYTE IN D IS 000h - LD E,A ; PUT ADDRESS OFFSET IN E - ADD HL,DE ; MULTIPLY BY 2, TOTAL MULTIPLICATION IS X 128 - ADD HL,DE ; CP/M SECTOR STARTING ADDRESS IN IDE HD SECTOR BUFFER - ; COPY CP/M SECTOR TO BDOS DMA ADDRESS BUFFER - POP DE ; RESTORE DE - CALL COPY_CPM_SECTOR ; - RET - -;___BLKSEC_______________________________________________________________________________________________ -; -; BLOCK 512 BYTE SECTOR FOR CP/M -; -;________________________________________________________________________________________________________ -BLKSEC: - ; COMPUTE STARTING ADDRESS OF CP/M SECTOR IN READ SECTOR BUFFER - LD HL,#SECTOR_BUFFER ; LOAD HL WITH SECTOR BUFFER ADDRESS - LD A,(SECTOR_INDEX) ; GET THE SECTOR INDEX (CP/M SECTOR OFFSET IN BUFFER) - RRCA ; MOVE BIT 0 TO BIT 7 - RRCA ; DO AGAIN - IN EFFECT MULTIPLY BY 64 - LD D,#0 ; PUT RESULT AS 16 VALUE IN DE, UPPER BYTE IN D IS 000h - LD E,A ; PUT ADDRESS OFFSET IN E - ADD HL,DE ; CP/M SECTOR STARTING ADDRESS IN IDE HD SECTOR BUFFER - ADD HL,DE ; MULTIPLY BY 2, TOTAL MULTIPLICATION IS X 128 - LD (SECST),HL ; KEEP CP/M SECTOR ADDRESS FOR LATER USE - ; COPY CP/M SECTOR FROM BDOS DMA ADDRESS BUFFER - LD HL,(SECST) ; LOAD CP/M SECTOR ADDRESS (WHERE THE DATA IS TO BE WRITTEN) - LD D,H ; TRANSFER HL REGISTERS TO DE - LD E,L ; - LD HL,(DMAAD) ; LOAD HL WITH DMA ADDRESS (WHERE THE DATA TO BE WRITTEN IS) - CALL COPY_CPM_SECTOR ; - RET - -;___ISCUR_______________________________________________________________________________________________ -; -; IS CURRENT SECTOR IN BUFFER? -; -;________________________________________________________________________________________________________ -ISCUR: - LD HL,(PSECTOR) ; COMPARE REQUESTED SECTOR WITH SECTOR IN BUFFER - LD A,(CUSECTOR) ; - CP L ; - RET NZ ; LOW BYTE NOT EQUAL - LD A,(CUSECTOR+1) ; - CP H ; - RET NZ ; HIGH BYTE NOT EQUAL - LD HL,(PTRACK) ; COMPARE REQUESTED TRACK WITH TRACK IN BUFFER - LD A,(CUTRACK) ; - CP L ; LOW BYTE NOT EQUAL - RET NZ ; - LD A,(CUTRACK+1) ; - CP H ; - RET NZ ; HIGH BYTE NOT EQUAL - LD HL,(DISKNO) ; COMPARE REQUESTED DRIVE WITH DRIVE IN BUFFER - LD A,(CUDISK) ; - CP L ; - RET ; EXIT WITH RESULT - -;___READ_FLPY_DSK________________________________________________________________________________________ -; -; READ FLOPPY DISK -; -;________________________________________________________________________________________________________ - -READ_FLPY_DSK: - DI ; DISABLE INTERRUPTS - LD HL,#0 ; - ADD HL,SP ; GET STACK POINTER INTO HL - LD (PARKSTACK),HL ; SAVE STACK POINTER - LD SP,#FLOPPYSTACK ; - CALL TRFLSEC ; TRANSLATE SECTOR INFORMATION - CALL READ_FLPY_SEC ; - CALL DEBSEC ; DEBLOCK SECTOR - LD A,(ST1) ; LOAD RESULT CODE INTO A -READ_FLPY_DSK_EXIT: ; - LD SP,(PARKSTACK) ; RETURN STACK -;;;;; EI ; RE-ENABLE INTERRUPTS - RET - - -;___READ_FLPY_SEC________________________________________________________________________________________ -; -; READ A SECTOR FROM A FLOPPY DISK -; -;________________________________________________________________________________________________________ -READ_FLPY_SEC: - LD A,#0 ; RESET STATUS FLAG 1 - LD (ST1),A ; - CALL ISCUR ; IS CURRENT SECTOR ALREADY IN BUFFER - JP Z,READ_FLPY_SEC_OK - LD A,#20 ; 20 RETRIES - LD (RETRY),A ; - LD A,#2 ; 2 ITERATIONS OF RETRIES - LD (RETRY1),A ; -READ_FLPY_SEC_RETRY: ; - CALL FLOPPYREAD ; READ THE FLOPPY DISK SECTOR - LD A,(ST0) ; GET STATUS FLAG 0 - AND #0x0F8 ; MASK OF DRIVE AND HEAD SELECTION - LD B,A ; MOVE STATUS FLAG 0 TO B - LD A,(ST1) ; GET STATUS FLAG 1 - OR B ; IF ZERO READ WAS OK - JP Z,READ_FLPY_SEC_OK - LD A,(RETRY) ; READ NOT OK, DEC RETRY COUNTER - DEC A ; - LD (RETRY),A ; STORE NEW RETRY COUNTER - JP NZ,READ_FLPY_SEC_RETRY - CALL CYCLEFLOPPY ; CYCLE FLOPPY HEAD - LD A,#20 ; RESET TO 20 RETRIES - LD (RETRY),A ; STORE RETRY COUNTER - LD A,(RETRY1) ; DEC RETRY ITERATION COUNTER - DEC A ; - LD (RETRY1),A ; - JP NZ,READ_FLPY_SEC_RETRY - LD HL,#0x0FFFF ; SET INVALID CONDITION, BUFFER IS INVALID - LD (CUSECTOR),HL ; CURRENT PHYSICAL DISK SECTOR IN BUFFER - LD (CUTRACK),HL ; CURRENT PHYSICAL DISK TRACK IN BUFFER - RET ; -READ_FLPY_SEC_OK: ; - LD HL,(PSECTOR) ; STORE PHYSICAL SECTOR IN BUFFER - LD (CUSECTOR),HL ; - LD HL,(PTRACK) ; STORE PHYSICAL DISK TRACK IN BUFFER - LD (CUTRACK),HL ; - LD A,(DISKNO) ; STORE CURRENT DRIVE IN BUFFER - LD (CUDISK),A ; - RET - -;___READ_IDE_____________________________________________________________________________________________ -; -; READ FROM IDE HARD DISK -;________________________________________________________________________________________________________ - -READ_IDE: - DI ; DISABLE INTERRUPTS - LD HL,#0 ; - ADD HL,SP ; GET STACK POINTER INTO HL - LD (PARKSTACK),HL ; SAVE STACK POINTER - LD SP,#FLOPPYSTACK ; - ; DISABLE INTERRUPTS - CALL CONVERT_IDE_SECTOR_CPM - CALL IDE_READ_SECTOR ; READ THE IDE HARD DISK SECTOR - JP NC,READ_IDE_ERROR - CALL DEBSEC ; - LD SP,(PARKSTACK) ; RETURN STACK -;;;;; EI ; RE-ENABLE INTERRUPTS - LD A,#0 ; RETURN ERROR CODE READ SUCCESSFUL A=0 - RET ; -READ_IDE_ERROR: ; - LD SP,(PARKSTACK) ; RETURN STACK -;;;;; EI ; RE-ENABLE INTERRUPTS - LD A,#0x0FF ; RETURN ERROR CODE READ ERROR A=FF - RET - -;___READ_ATAPI_________________________________________________________________________________________ -; -; READ FROM ATAPI DEVICE -;________________________________________________________________________________________________________ -READ_ATAPI: - LD A,#0x0FF ; 255 RETRIES - LD (RETRY),A ; -READ_ATAPI_RETRY: - LD A,#0x10 ; SET TO SECONDARY DEVICE - LD (IDEDEVICE),A ; - DI ; DISABLE INTERRUPTS - LD HL,#0 ; - ADD HL,SP ; GET STACK POINTER INTO HL - LD (PARKSTACK),HL ; SAVE STACK POINTER - LD SP,#FLOPPYSTACK ; - CALL CONVERT_IDE_SECTOR_CPM - CALL ATAPI_READ_SECTOR - JP NC,READ_ATAPI_ERROR - CALL DEBSEC ; - LD SP,(PARKSTACK) ; RETURN STACK -;;;;; EI ; RE-ENABLE INTERRUPTS - LD A,#0 ; RETURN ERROR CODE READ SUCCESSFUL A=0 - RET ; -READ_ATAPI_ERROR: - LD A,(RETRY) ; READ NOT OK, DEC RETRY COUNTER - DEC A ; - LD (RETRY),A ; STORE NEW RETRY COUNTER - JP NZ,READ_ATAPI_RETRY - LD SP,(PARKSTACK) ; RETURN STACK -;;;;; EI ; RE-ENABLE INTERRUPTS - LD A,#0x0FF ; RETURN ERROR CODE READ ERROR A=FF - RET ; - -READ_HDPART4: - ; STUB - RET - -;___WRITE______________________________________________________________________________________________ -; -; HANDLE CP/M WRITE CALL -; -;________________________________________________________________________________________________________ -WRITE: - DI ; DISABLE INTERRUPTS - LD A,(DISKNO) ; GET DRIVE - CP #1 ; FIND OUT WHICH DRIVE IS BEING REQUESTED - .IF CONDUSEFLOPPY - JP Z,WRITE_FLP_DSK ; - .ELSE - JP Z,WRITE_RAM_DISK ; WRITE TO 448K RAM DISK - .ENDIF - CP #0 ; - JP Z,WRITE_RAM_DISK ; WRITE TO 448K RAM DISK - CP #2 ; - JP Z,WRITE_IDE ; WRITE TO 8 MB IDE HARD DISK, PARTITION 2 - CP #3 ; - .IF CONDUSEATAPI - JP Z,WRITE_ATAPI ; WRITE TO 8 MB IDE HARD DISK, PARTITION 3 - .ELSE - JP Z,WRITE_RAM_DISK ; WRITE TO 448K RAM DISK - .ENDIF - CP #4 ; - JP Z,WRITE_HDPART4 ; WRITE TO 1 MB IDE HARD DISK, PARTITION 4 - - -;___RDONLY______________________________________________________________________________________________ -; -; HANDLE WRITE TO READ ONLY -; -; SENDS A MESSAGE TO TERMINAL THAT ROM DRIVE IS NOT WRITEABLE -; DOES A PAUSE THEN RETURNS TO CPM WITH ERROR FLAGGED THIS IS -; DONE TO ALLOW A POSSIBLE GRACEFUL EXIT (SOME APPS MAY PUKE) -;________________________________________________________________________________________________________ -RDONLY: - LD HL,#TXT_RO_ERROR ; SET HL TO START OF ERROR MESSAGE - CALL PRTMSG ; PRINT ERROR MESSAGE - LD A,#1 ; SEND BAD SECTOR ERROR BACK - ; BDOS WILL ALSO PRINT ITS OWN ERROR MESSAGE - RET - -;___WRITE_RAM_DISK_____________________________________________________________________________________ -; -; WRITE RAM DISK -;________________________________________________________________________________________________________ -WRITE_RAM_DISK: - LD HL,#SECTOR_BUFFER ; LOAD HL WITH TEMP BUF ADDRESS - LD E,L ; - LD D,H ; GET IT INTO DE - LD HL,(DMAAD) ; GET DMA ADDRESS - CALL COPY_CPM_SECTOR ; - CALL SECPAGE ; GET RAM PAGE WRITE ADDRESS - CALL PAGERB ; SET PAGER WITH DRIVE AND TRACK - LD HL,(SECST) ; LOAD HL WITH DMA ADDRESS (WHERE TO WRITE TO) - LD E,L ; - LD D,H ; GET IT INTO DE - LD HL,#SECTOR_BUFFER ; GET TEMP BUFFER ADDRESS - CALL COPY_CPM_SECTOR ; - CALL RPAGE ; SET BACK TO RAM - LD A,(DISKNO) ; STORE CURRENT DRIVE IN BUFFER - LD (CUDISK),A ; - LD A,#0 ; -;;;;; EI ; RE-ENABLE INTERRUPTS - RET - -;___WRITE_FLP_DSK_____________________________________________________________________________________ -; -; WRITE FLOPPY DISK -;________________________________________________________________________________________________________ -WRITE_FLP_DSK: - DI ; DISABLE INTERRUPTS - LD HL,#0 ; - ADD HL,SP ; MOVE STACK POINTER TO HL - LD (PARKSTACK),HL ; SAVE STACK POINTER - LD SP,#FLOPPYSTACK ; - CALL TRFLSEC ; TRANSLATE SECTOR INFORMATION - CALL READ_FLPY_SEC ; - LD A,(ST1) ; GET STATUS CODE - JP NZ,WRITE_FLP_DSK_OK -WRITE_READ_FLPY_DSK_OK: ; - CALL BLKSEC ; BLOCK SECTOR - ; IDE HD SECTOR IS NOW UPDATED WITH CURRENT CP/M SECTOR DATA SO WRITE TO DISK - LD A,#20 ; 20 RETRIES - LD (RETRY),A ; -WRITE_FLP_DSK_RETRY: ; - CALL FLOPPYWRITE ; WRITE THE FLOPPY DISK SECTOR - LD A,(ST0) ; GET STATUS CODE 0 - AND #0x0F8 ; MASK OF DRIVE AND HEAD SELECTION - LD B,A ; MOVE STATUS CODE 0 TO B - LD A,(ST1) ; GET STATUS CODE 1 - OR B ; IF ZERO WRITE WAS OK - JP Z,WRITE_FLP_DSK_OK ; - LD A,(RETRY) ; BAD WRITE, DEC RETRY COUNTER - DEC A ; - LD (RETRY),A ; STORE NEW RETRY COUNTER - JP NZ,WRITE_FLP_DSK_RETRY ; -WRITE_FLP_DSK_OK: ; - LD SP,(PARKSTACK) ; RESTORE STACK - LD A,(ST1) ; GET STATUS CODE 1 -;;;;; EI ; RE-ENABLE INTERRUPTS - RET - - - -;___WRITE_IDE____________________________________________________________________________________________ -; -; WRITE TO IDE DEVICE -;________________________________________________________________________________________________________ -WRITE_IDE: - DI ; DISABLE INTERRUPTS - LD HL,#0 ; - ADD HL,SP ; GET STACK POINTER INTO HL - LD (PARKSTACK),HL ; SAVE STACK POINTER - LD SP,#FLOPPYSTACK ; - CALL CONVERT_IDE_SECTOR_CPM ; - CALL IDE_READ_SECTOR ; READ THE IDE HARD DISK SECTOR - JP NC,WRITE_IDE_ERROR ; - CALL BLKSEC ; DEBLOCK SECTOR - CALL IDE_WRITE_SECTOR ; WRITE THE UPDATED IDE HARD DISK SECTOR - LD SP,(PARKSTACK) ; RESTORE STACK -;;;;; EI ; RE-ENABLE INTERRUPTS - LD A,#0 ; RETURN ERROR CODE WRITE SUCCESSFUL A=0 - RET ; -WRITE_IDE_ERROR: ; - LD SP,(PARKSTACK) ; RESTORE STACK -;;;;; EI ; RE-ENABLE INTERRUPTS - LD A,#0x0FF ; RETURN ERROR CODE WRITE ERROR A=FF - RET - -;___WRITE_ATAPI__________________________________________________________________________________________ -; -; WRITE TO ATAPI DEVICE -;________________________________________________________________________________________________________ -WRITE_ATAPI: - LD A,#0x10 ; SET TO SECONDARY DEVICE - LD (IDEDEVICE),A ; - DI ; DISABLE INTERRUPTS - LD HL,#0 ; - ADD HL,SP ; GET STACK POINTER INTO HL - LD (PARKSTACK),HL ; SAVE STACK POINTER - LD SP,#FLOPPYSTACK ; - ; - CALL CONVERT_IDE_SECTOR_CPM ; - ; - CALL ATAPI_READ_SECTOR ; - JP NC,WRITE_ATAPI_ERROR ; - CALL BLKSEC ; DEBLOCK SECTOR - CALL ATAPI_WRITE_SECTOR ; - ; - LD SP,(PARKSTACK) ; RESTORE STACK -;;;;; EI ; RE-ENABLE INTERRUPTS - LD A,#0 ; RETURN ERROR CODE WRITE SUCCESSFUL A=0 - RET ; -WRITE_ATAPI_ERROR: ; - LD SP,(PARKSTACK) ; RESTORE STACK -;;;;; EI ; RE-ENABLE INTERRUPTS - LD A,#0x0FF ; RETURN ERROR CODE WRITE ERROR A=FF - RET ; - -WRITE_HDPART4: - ; STUB - RET - - -;___PRTMSG_______________________________________________________________________________________________ -; -; PRINT MESSAGE POINTED TO BY HL ON CONSOLE DEVICE -;________________________________________________________________________________________________________ -PRTMSG: - LD A,(HL) ; GET CHARACTER TO A - CP #END ; TEST FOR END BYTE - JP Z,PRTMSG1 ; JUMP IF END BYTE IS FOUND - LD C,A ; PUT CHAR TO PRINT VALUE IN REG C FOR CONOUT - CALL CONOUT ; SEND CHARACTER TO CONSOLE FROM REG C - INC HL ; INC POINTER, TO NEXT CHAR - JP PRTMSG ; TRANSMIT LOOP -PRTMSG1: - RET - - -;___SECPAGE_______________________________________________________________________________________________ -; -; UTILITY ROUTINE FOR SECTOR TO PAGE ADDRESS -;________________________________________________________________________________________________________ -SECPAGE: - LD HL,(SECTOR) ; GET SECTOR INTO HL - ADD HL,HL ; SHIFT BITS 1 TO LEFT (*2) - ADD HL,HL ; SHIFT BITS 1 TO LEFT (*4) - ADD HL,HL ; SHIFT BITS 1 TO LEFT (*8) - ADD HL,HL ; SHIFT BITS 1 TO LEFT (*16) - ADD HL,HL ; SHIFT BITS 1 TO LEFT (*32) - ADD HL,HL ; SHIFT BITS 1 TO LEFT (*64) - ADD HL,HL ; SHIFT BITS 1 TO LEFT (*128) - LD (SECST),HL ; SAVE SECTOR STARTING ADDRESS - RET - -;___PAGERB_______________________________________________________________________________________________ -; -; PAGER BYTE CREATION -; ASSEMBLES DRIVE AND TRACK AND SENDS IT TO PAGER PORT -;________________________________________________________________________________________________________ -PAGERB: - LD HL,(TRACK) ; LOAD TRACK INTO HL - LD A,(DISKNO) ; LOAD DISK INTO A - CP #5 ; IS ROM? - JP Z,ROMD ; READ FROM 1M ROM DISK - CP #6 ; IS ROM? - JP Z,ROMD ; READ FROM 22K ROM DISK - AND #1 ; MASK FOR 1 BIT OF DRIVE SELECT - RRCA ; MOVE BIT 0 TO BIT 7 - OR L ; OR L WITH ACC TO COMBINE TRACK AND DRIVE - OUT (MPCL_RAM),A ; SEND TO RAM PORT MAPPER - LD (PAGER),A ; SAVE COPY (JUST BECAUSE) - RET ; -ROMD: ; - LD A,#5 ; - AND #1 ; MASK FOR 1 BIT OF DRIVE SELECT - RRCA ; MOVE BIT 0 TO BIT 7 - OR L ; OR L WITH ACC TO COMBINE TRACK AND DRIVE - AND #0x7F ; STRIP OFF BIT 7 (ROM_ENABLE BIT) - OUT (MPCL_ROM),A ; SEND TO ROM PORT MAPPER - LD (PAGER),A ; SAVE COPY (JUST BECAUSE) - LD (DB_PAGER),A ; SAVE COPY (JUST BECAUSE) (DEBUG) - RET - -;___RPAGE_______________________________________________________________________________________________ -; -; RESET PAGER BACK TO RAM -;________________________________________________________________________________________________________ -RPAGE: - LD A,#0x80 ; DESELECT ROM PAGE - OUT (MPCL_ROM),A ; SELECT RAM - LD A,#0 ; SET TO RAM, TRACK 0 - OUT (MPCL_RAM),A ; SELECT RAM - LD (PAGER),A ; SAVE COPY OF PAGER BYTE - RET - -;___COPY_CPM_SECTOR______________________________________________________________________________________ -; -; COPIES ONE CPM SECTOR FROM ONE MEMORY ADDRESS TO ANOTHER -; INPUT -; DE SOURCE ADDRESS -; HL TARGET ADDRESS -; USES C REGISTER -;________________________________________________________________________________________________________ -COPY_CPM_SECTOR: - LD BC,#128 ; BC IS COUNTER FOR FIXED SIZE TRANSFER (128 BYTES) - LDIR ; TRANSFER - RET - -;___CONVERT_IDE_SECTOR_CPM________________________________________________________________________________ -; -; COMPUTES WHERE THE CP/M SECTOR IS IN THE LBA PARTITION -; LBA HD SECTORS ARE 512 BYTES EACH, CP/M SECTORS ARE 128 BYTES EACH -; MAXIMUM SIZE OF CP/M DISK IS 8 MB = 65536 (16 BITS) X 128 BYTES PER SECTOR -; LBA HD PARTITION CAN HAVE AT MOST 16777215 IDE SECTORS -> 67108860 CP/M SECTORS -; EACH IDE HD SECTOR CONTAINS 4 ADJACENT CP/M SECTORS -; -; -; INPUT: -; - CP/M TRACK AND SECTOR 16 BIT WORDS -; -; OUTPUT: -; IDE TARGET SECTOR (SENT TO IDE HD CONTROLLER FOR READ OPERATION) -; - LOWER 16 BITS STORED IN LBA_TARGET_LO -; - UPPER 16 BITS STORED IN LBA_TARGET_HI -; CP/M TO IDE HD SECTOR MAPPING PARAMETER STORED IN SECTOR_INDEX -; - 8 BIT VALUE WITH 4 LEGAL STATES (00, 01, 02, 04) WHICH IS -; TO BE USED TO COMPUTE STARTING ADDRESS OF 128 BYTE CP/M SECTOR ONCE -; 512 BYTE IDE HD SECTOR READ INTO MEMORY BUFFER -; LBA ADDRESS FORMAT = 00TTTTSS -; -; ROTATE WITH CARRY 16 BIT TRACK,SECTOR VALUE IN HL TO GET 14 BIT IDE HD -; TARGET SECTOR IN PARTITION -; KEEP LAST TWO BITS IN B FOR IDE HD SECTOR TO CP/M SECTOR TRANSLATION -; COMPUTE SECTOR_INDEX -;________________________________________________________________________________________________________ -CONVERT_IDE_SECTOR_CPM: - - LD A,(TRACK) ; LOAD TRACK # (LOW BYTE) - LD H,A ; - LD A,(SECTOR) ; LOAD SECTOR# (LOW BYTE) - LD L,A ; - CALL RRA16 ; ROTATE 'HL' RIGHT (DIVIDE BY 2) - CALL RRA16 ; ROTATE 'HL' RIGHT (DIVIDE BY 2) - LD A,(TRACK+1) ; GET HIGH BYTE OF TRACK INTO A - SLA A ; - SLA A ; - SLA A ; - SLA A ; - SLA A ; - SLA A ; - OR H ; - LD H,A ; - LD A,(TRACK+1) ; GET HIGH BYTE OF TRACK INTO A - SRL A ; - SRL A ; - LD (LBA_TARGET_HI),A ; - LD A,L ; - LD (LBA_TARGET_LO),A ; LBA REGISTER IS 00TTTTSS / 4 - LD A,H ; - LD (LBA_TARGET_LO+1),A ; - LD A,#0 ; - LD (LBA_TARGET_HI+1),A ; - ; - LD HL,(LBA_TARGET_LO) ; STORE PHYSICAL SECTOR - LD (PSECTOR),HL ; - LD HL,(LBA_TARGET_HI) ; STORE PHYSICAL TRACK - LD (PTRACK),HL ; - LD A,(SECTOR) ; LOAD SECTOR # - AND #0b000000011 ; - LD (SECTOR_INDEX),A ; LOCATES WHERE THE 128 BYTE CP/M SECTOR - ; IS WITHIN THE 512 BYTE IDE HD SECTOR - ; COMPUTE WHICH IDE HD SECTOR TO READ TO WITHIN 4 CP/M SECTORS - ; SHIFTS 16 BIT PARTITION OFFSET TO THE RIGHT 2 BITS AND ADDS RESULT TO - ; IDE HD PARTITION STARTING SECTOR - ; SHIFT PARTITION OFFSET RIGHT 1 BIT - RET -RRA16: - SCF ; - CCF ; CLEAR CARRY FLAG - LD A,H ; 16 BIT ROTATE HL WITH CARRY - RRA ; - LD H,A ; ROTATE HL RIGHT 1 BIT (DIVIDE BY 2) - LD A,L ; - RRA ; - LD L,A ; - RET - - -;___IDE_READ_SECTOR______________________________________________________________________________________ -; -; READ IDE SECTOR -;________________________________________________________________________________________________________ -IDE_READ_SECTOR: - CALL ISCUR ; IS CURRENT SECTOR IN BUFFER? - JP Z,IDE_READ_SECTOR_OK ; - CALL IDE_WAIT_BUSY_READY ; MAKE SURE DRIVE IS READY TO PROCEED - RET NC ; ERROR, RETURN - CALL IDE_SETUP_LBA ; TELL DRIVE WHAT SECTOR IS REQUIRED - LD A,#0x20 ; - OUT (IDESTTS),A ; 020h = IDE 'READ SECTOR' COMMAND -IDE_SREX: ; - CALL IDE_WAIT_BUSY_READY ; MAKE SURE DRIVE IS READY TO PROCEED - RET NC ; ERROR, RETURN - CALL IDE_TEST_ERROR ; ENSURE NO ERROR WAS REPORTED - RET NC ; ERROR, RETURN - CALL IDE_WAIT_BUFFER ; WAIT FOR FULL BUFFER SIGNAL FROM DRIVE - RET NC ; ERROR, RETURN - CALL IDE_READ_BUFFER ; GRAB THE 256 WORDS FROM THE BUFFER - SCF ; CARRY = 1 ON RETURN = OPERATION OK -IDE_READ_SECTOR_OK: ; - LD HL,(PSECTOR) ; STORE PHYSICAL SECTOR IN BUFFER - LD (CUSECTOR),HL ; - LD HL,(PTRACK) ; STORE PHYSICAL DISK TRACK IN BUFFER - LD (CUTRACK),HL ; - LD A,(DISKNO) ; STORE CURRENT DRIVE IN BUFFER - LD (CUDISK),A ; - SCF ; CARRY = 1 ON RETURN = OPERATION OK - RET - -;___IDE_WRITE_SECTOR_____________________________________________________________________________________ -; -; WRITE IDE SECTOR -;________________________________________________________________________________________________________ -IDE_WRITE_SECTOR: - CALL IDE_WAIT_BUSY_READY ; MAKE SURE DRIVE IS READY TO PROCEED - RET NC ; ERROR, RETURN - CALL IDE_SETUP_LBA ; TELL DRIVE WHAT SECTOR IS REQUIRED - LD A,#0x30 ; - OUT (IDESTTS),A ; 030h = IDE 'WRITE SECTOR' COMMAND - CALL IDE_WAIT_BUSY_READY ; - RET NC ; ERROR, RETURN - CALL IDE_TEST_ERROR ; ENSURE NO ERROR WAS REPORTED - RET NC ; ERROR, RETURN - CALL IDE_WAIT_BUFFER ; WAIT FOR BUFFER READY SIGNAL FROM DRIVE - RET NC ; ERROR, RETURN - CALL IDE_WRITE_BUFFER ; SEND 256 WORDS TO DRIVE'S BUFFER - CALL IDE_WAIT_BUSY_READY ; MAKE SURE DRIVE IS READY TO PROCEED - RET NC ; ERROR, RETURN - CALL IDE_TEST_ERROR ; ENSURE NO ERROR WAS REPORTED - RET NC ; ERROR, RETURN - SCF ; CARRY = 1 ON RETURN = OPERATION OK - RET - -;___IDE_SOFT_RESET_______________________________________________________________________________________ -; -; RESET IDE CHANNEL -;________________________________________________________________________________________________________ -IDE_SOFT_RESET: - .IF CONDIDESOFT ; - LD A,#0b000000110 ; NO INTERRUPTS, RESET DRIVE = 1 - OUT (IDECTRL),A ; - LD A,#0b000000010 ; NO INTERRUPTS, RESET DRIVE = 0 - OUT (IDECTRL),A ; - CALL IDE_WAIT_BUSY_READY ;THIS TAKES A COUPLE OF SECONDS - RET - .ELSE - ; SKIP THIS IF NO IDE DRIVE WHICH SPEEDS UP REBOOTS AND STARTUPS - RET - .ENDIF - -;___ATAPI_WAIT_BUSY_READY________________________________________________________________________________ -; -; WAIT FOR ATAPI CHANNEL TO BE READY -;________________________________________________________________________________________________________ -ATAPI_WAIT_BUSY_READY: - LD DE,#0 ; CLEAR OUT DE -ATAPI_WBSY: ; - LD B,#0x0F0 ; SETUP TIMEOUT -ATAPI_DLP: ; - DJNZ ATAPI_DLP ; - INC DE ; - LD A,D ; - OR E ; - JR Z,ATAPI_TO ; - IN A,(IDESTTS) ; READ ERROR REG - AND #0b010000000 ; MASK OFF BUSY BIT - JR NZ,ATAPI_WBSY ; WE WANT BUSY(7) TO BE 0 - SCF ; CARRY 1 = OK - RET ; -ATAPI_TO: ; - XOR A ; CARRY 0 = TIMED OUT - RET ; - -;___IDE_WAIT_DRQ_READY___________________________________________________________________________________ -; -; WAIT FOR IDE CHANNEL TO BE READY -;________________________________________________________________________________________________________ -IDE_WAIT_DRQ_READY: - IN A,(IDESTTS) ; READ ERROR REG - AND #0b000001000 ; MASK OFF RDY BIT - JR Z,IDE_WAIT_DRQ_READY ; WE WANT DRQ(3) TO BE 1 - RET - -;___IDE_WAIT_DRQ_ZERO____________________________________________________________________________________ -; -; WAIT FOR IDE DRQ TO BE ZERO -;________________________________________________________________________________________________________ -IDE_WAIT_DRQ_ZERO: - IN A,(IDESTTS) ; READ ERROR REG - AND #0b000001000 ; MASK OFF RDY BIT - JR NZ,IDE_WAIT_DRQ_ZERO ; WE WANT DRQ(3) TO BE 0 - RET - -;___IDE_WAIT_BUSY_READY___________________________________________________________________________________ -; -; WAIT FOR IDE CHANNEL TO BE READY -;________________________________________________________________________________________________________ -IDE_WAIT_BUSY_READY: - LD DE,#0 ; CLEAR DE -IDE_WBSY: ; - LD B,#5 ; SETUP TIMEOUT -IDE_DLP: ; - DEC B ; - JP NZ,IDE_DLP ; - INC DE ; - LD A,D ; - OR E ; - JP Z,IDE_TO ; - IN A,(IDESTTS) ; READ ERROR REG - AND #0b011000000 ; MASK OFF BUSY AND RDY BITS - XOR #0b001000000 ; WE WANT BUSY(7) TO BE 0 AND RDY(6) TO BE 1 - JP NZ,IDE_WBSY ; - SCF ; CARRY 1 = OK - RET -IDE_TO: - XOR A ; CARRY 0 = TIMED OUT - RET - -;___IDE_TEST_ERROR_______________________________________________________________________________________ -; -; CHECK FOR IDE ERROR CONDITION -;________________________________________________________________________________________________________ -IDE_TEST_ERROR: - SCF ; - IN A,(IDESTTS) ; - LD B,A ; - AND #0b000000001 ; TEST ERROR BIT - SCF ; - RET Z ; - LD A,B ; - AND #0b000100000 ; - SCF ; - JP NZ,IDE_ERR ; TEST WRITE ERROR BIT - IN A,(IDEERR) ; READ ERROR FLAGS -IDE_ERR: - OR A ; CARRY 0 = ERROR - RET ; IF A = 0, IDE BUSY TIMED OUT - -;___IDE_WAIT_BUFFER_______________________________________________________________________________________ -; -; WAIT FOR DATA BUFFER READY -;________________________________________________________________________________________________________ -IDE_WAIT_BUFFER: - LD DE,#0 ; -IDE_WDRQ: ; - LD B,#5 ; -IDE_BLP: ; - DEC B ; - JP NZ,IDE_BLP ; - INC DE ; - LD A,D ; - OR E ; - JP Z,IDE_TO2 ; - IN A,(IDESTTS) ; WAIT FOR DRIVE'S 512 BYTE READ BUFFER - AND #0b000001000 ; TO FILL (OR READY TO FILL) - JP Z,IDE_WDRQ ; - SCF ; CARRY 1 = OK - RET ; -IDE_TO2: ; - XOR A ; CARRY 0 = TIMED OUT - RET ; - -;___IDE_READ_BUFFER_______________________________________________________________________________________ -; -; READ IDE BUFFER -;________________________________________________________________________________________________________ -IDE_READ_BUFFER: - PUSH HL ; - LD HL,#SECTOR_BUFFER ; - LD B,#0 ; 256 WORDS (512 BYTES PER SECTOR) -IDEBUFRD: ; - IN A,(IDELO) ; LOW BYTE OF WORD FIRST - LD (HL),A ; - IN A,(IDEHI) ; THEN HIGH BYTE OF WORD - INC HL ; - LD (HL),A ; - INC HL ; - DEC B ; - JP NZ,IDEBUFRD ; - POP HL ; - RET - -;___IDE_WRITE_BUFFER_______________________________________________________________________________________ -; -; WRITE TO IDE BUFFER -;________________________________________________________________________________________________________ -IDE_WRITE_BUFFER: - PUSH HL ; - LD HL,#SECTOR_BUFFER ; - LD B,#0 ; 256 WORDS (512 BYTES PER SECTOR) -IDEBUFWT: - INC HL ; - LD A,(HL) ; - DEC HL ; - OUT (IDEHI),A ; SET UP HIGH LATCHED BYTE BEFORE - LD A,(HL) ; - OUT (IDELO),A ; WRITING WORD WITH WRITE TO LOW BYTE - INC HL ; - INC HL ; - DEC B ; - JP NZ,IDEBUFWT ; - POP HL ; - RET - -;___IDE_SETUP_LDA________________________________________________________________________________________ -; -; SETUP IDE DRIVE FOR LDA OPERATION -;________________________________________________________________________________________________________ -IDE_SETUP_LBA: - LD A,(LBA_TARGET_LO) ; LOAD LBA REGISTER 0 WITH SECTOR ADDRESS TO READ - LD (IDE_LBA0),A ; - LD A,(LBA_TARGET_LO+1) ; LOAD LBA REGISTER 1 WITH SECTOR ADDRESS TO READ - LD (IDE_LBA1),A ; - LD A,(LBA_TARGET_HI) ; LOAD LBA REGISTER 2 WITH SECTOR ADDRESS TO READ - LD (IDE_LBA2),A ; - LD A,(LBA_TARGET_HI+1) ; LOAD LBA REGISTER 3 WITH SECTOR ADDRESS TO READ - AND #0b000001111 ; ONLY LOWER FOUR BITS ARE VALID - ADD A,#0b011100000 ; ENABLE LBA BITS 5:7=111 IN IDE_LBA3 - LD (IDE_LBA3),A ; - ; READ IDE HD SECTOR - LD A,#1 ; - OUT (IDESECTC),A ; SET SECTOR COUNT = 1 - ; - LD A,(IDE_LBA0) ; - OUT (IDESECTN),A ; SET LBA 0:7 - ; - LD A,(IDE_LBA1) ; - OUT (IDECYLLO),A ; SET LBA 8:15 - ; - LD A,(IDE_LBA2) ; - OUT (IDECYLHI),A ; SET LBA 16:23 - ; - LD A,(IDE_LBA3) ; - AND #0b000001111 ; LOWEST 4 BITS USED ONLY - OR #0b011100000 ; TO ENABLE LBA MODE - OUT (IDEHEAD),A ; SET LBA 24:27 + BITS 5:7=111 - .IF CONDUSEDSKY - CALL IDESEGDISPLAY ; - .ENDIF - RET - -;___ATAPI_SOFT_RESET_____________________________________________________________________________________ -; -; RESET ATAPI BUS -;________________________________________________________________________________________________________ -ATAPI_SOFT_RESET: - LD A,#0b000001110 ;NO INTERRUPTS, RESET DRIVE = 1 - OUT (IDECTRL),A ; - CALL DELAY24 ; - LD A,#0b000001010 ;NO INTERRUPTS, RESET DRIVE = 0 - OUT (IDECTRL),A ; - CALL ATAPI_WAIT_BUSY_READY ; - RET NC ; ERROR, RETURN - CALL ATAPI_DEVICE_SELECTION ; - CALL DELAY24 ; - CALL REQUEST_SENSE_LOOP ; - RET - -;___REQUEST_SENSE_LOOP____________________________________________________________________________________ -; -; ATAPI_REQUEST SENSE DATA -;_________________________________________________________________________________________________________ -REQUEST_SENSE_LOOP: - LD HL,#ATAPI_REQUEST_SENSE ; - CALL ATAPI_SEND_PACKET ; - CALL ATAPI_WAIT_BUSY_READY ; MAKE SURE DRIVE IS READY TO PROCEED - RET NC ; ERROR, RETURN - LD B,#0 ; 256 WORDS (512 BYTES PER SECTOR) -REQUEST_SENSE_LOOP1: ; - IN A,(IDELO) ; - INC IX ; - IN A,(IDEHI) ; - INC IX ; - DJNZ REQUEST_SENSE_LOOP1 ; - RRD ; DELAY ONLY - IN A,(IDESTTS) ;READ ERROR REG - AND #0b000000001 ;MASK OFF BIT - JR NZ,REQUEST_SENSE_LOOP ; - RET - -;___ATAPI_DEVICE_SELECTION________________________________________________________________________________ -; -; ATAPI DEVICE SELECTION -;_________________________________________________________________________________________________________ -ATAPI_DEVICE_SELECTION: - - LD A,(IDEDEVICE) ; SELECTS DEVICE - OR #0x0A0 ; - OUT (IDEHEAD),A ; - RET ; - - - -;__ATAPI_READ_SECTOR_____________________________________________________________________________________________________________ -; READ ATAPI SECTOR -; -; D E H L = SECTOR (DOUBLE WORD) TO READ -;________________________________________________________________________________________________________________________________ -ATAPI_READ_SECTOR: - CALL ISCUR ; - JP Z,ATAPI_READ_DATA_EXIT ; - LD A,(LBA_TARGET_LO) ; LOAD LBA REGISTER 0 WITH SECTOR ADDRESS TO READ - LD (READ_DISK_PACKET+5),A ; - LD A,(LBA_TARGET_LO+1) ; LOAD LBA REGISTER 1 WITH SECTOR ADDRESS TO READ - LD (READ_DISK_PACKET+4),A ; - LD A,(LBA_TARGET_HI) ; LOAD LBA REGISTER 2 WITH SECTOR ADDRESS TO READ - LD (READ_DISK_PACKET+3),A ; - LD A,(LBA_TARGET_HI+1) ; LOAD LBA REGISTER 3 WITH SECTOR ADDRESS TO READ - LD (READ_DISK_PACKET+2),A ; - .IF CONDUSEDSKY - CALL ATAPISEGDISPLAY ; - .ENDIF - CALL REQUEST_SENSE_LOOP ; GET ATAPI SENSE CODES TO CLEAR ERRORS - LD HL,#READ_DISK_PACKET ; SET POINTER TO READ SECTOR PACKET - CALL ATAPI_SEND_PACKET ; SEND PACKET COMMAND - CALL ATAPI_WAIT_BUSY_READY ; MAKE SURE DRIVE IS READY TO PROCEED - RET NC ; ERROR, RETURN - LD B,#0 ; 256 WORDS (512 BYTES PER SECTOR) - LD IX,#SECTOR_BUFFER ; - IN A,(IDESTTS) ; READ REG - AND #0b000001000 ; MASK OFF BIT - CP #8 ; IS DATA WAITING? - JR NZ,ATAPI_READ_DATA_EXIT ; NO, EXIT -ATAPI_READ_DATA_LOOP: - IN A,(IDELO) ; - - LD (IX),A ; - - INC IX ; - IN A,(IDEHI) ; - - LD (IX),A ; - - INC IX ; - DJNZ ATAPI_READ_DATA_LOOP ; -ATAPI_READ_DATA_EXIT: ; - LD HL,(PSECTOR) ; STORE PHYSICAL SECTOR IN BUFFER - LD (CUSECTOR),HL ; - LD HL,(PTRACK) ; STORE PHYSICAL DISK TRACK IN BUFFER - LD (CUTRACK),HL ; - LD A,(DISKNO) ; STORE CURRENT DRIVE IN BUFFER - LD (CUDISK),A ; - SCF ; CARRY = 1 ON RETURN = OPERATION OK - RET ; - - - -;__ATAPI_WRITE_SECTOR_____________________________________________________________________________________________________________ -; WRITE ATAPI SECTOR -; -; D E H L = SECTOR (DOUBLE WORD) TO WRITE -;________________________________________________________________________________________________________________________________ -ATAPI_WRITE_SECTOR: - - LD A,(LBA_TARGET_LO) ; LOAD LBA REGISTER 0 WITH SECTOR ADDRESS TO READ - LD (WRITE_DISK_PACKET+5),A ; - LD A,(LBA_TARGET_LO+1) ; LOAD LBA REGISTER 1 WITH SECTOR ADDRESS TO READ - LD (WRITE_DISK_PACKET+4),A ; - LD A,(LBA_TARGET_HI) ; LOAD LBA REGISTER 2 WITH SECTOR ADDRESS TO READ - LD (WRITE_DISK_PACKET+3),A ; - LD A,(LBA_TARGET_HI+1) ; LOAD LBA REGISTER 3 WITH SECTOR ADDRESS TO READ - LD (WRITE_DISK_PACKET+2),A ; - .IF CONDUSEDSKY - CALL ATAPISEGDISPLAY ; - .ENDIF - CALL REQUEST_SENSE_LOOP ; - LD HL,#WRITE_DISK_PACKET ; SET POINTER TO WRITE PACKET COMMAND - CALL ATAPI_SEND_PACKET ; SEND THE PACKET COMMAND - CALL ATAPI_WAIT_BUSY_READY ; MAKE SURE DRIVE IS READY TO PROCEED - RET NC ; ERROR, RETURN - LD B,#0 ; 256 WORDS (512 BYTES PER SECTOR) - LD IX,#SECTOR_BUFFER ; -ATAPI_WRITE_DATA_LOOP: - IN A,(IDESTTS) ; READ REG - - LD A,(IX) ; - - PUSH AF ; - INC IX ; - - LD A,(IX) ; - - OUT (IDEHI),A ; - POP AF ; - OUT (IDELO),A ; - INC IX ; - DJNZ ATAPI_WRITE_DATA_LOOP ; - SCF ; CARRY = 1 ON RETURN = OPERATION OK - RET ; - - - - -;__ATAPI_SEND_PACKET_____________________________________________________________________________________________________________ -; SEND PACKET POINTED TO BY HL TO ATAPI DRIVE -; -;________________________________________________________________________________________________________________________________ -ATAPI_SEND_PACKET: - - CALL ATAPI_WAIT_BUSY_READY ; MAKE SURE DRIVE IS READY TO PROCEED - RET NC ; ERROR, RETURN - CALL IDE_WAIT_DRQ_ZERO ; - ; - LD A,#0x0A ; - OUT (IDECTRL),A ; DISABLE INT - LD A,#0 ; - OUT (IDEERR),A ; - LD A,#0 ; - OUT (IDESECTC),A ; - LD A,#0 ; - OUT (IDESECTN),A ; - LD A,#0 ; - OUT (IDECYLLO),A ; - LD A,#0x60 ; - OUT (IDECYLHI),A ; - LD A,(IDEDEVICE) ; - OUT (IDEHEAD),A ; BIT 4 SELECTS DEVICE - LD A,#0x0A0 ; - OUT (IDESTTS),A ; - ; - CALL IDE_WAIT_DRQ_READY ; MAKE SURE DRIVE IS READY TO PROCEED - ; - LD B,#6 ; SEND 12 BYTES (6 WORDS) - ; -ATAPI_SEND_PACKET_LOOP: - LD A,(HL) ; GET BYTE - LD D,A ; STORE LOW BYTE IN D - INC HL ; INC POINTER - LD A,(HL) ; GET HIGH BYTE - OUT (IDEHI),A ; STORE HIGH BYTE - LD A,D ; MOVE LOW BYTE INTO A - OUT (IDELO),A ; STORE LOW BYTE - INC HL ; INC POINTER - IN A,(IDECTRL) ; GET STATUS - DJNZ ATAPI_SEND_PACKET_LOOP ; LOOP - ; - CALL ATAPI_WAIT_BUSY_READY ; MAKE SURE DRIVE IS READY TO PROCEED - RET NC ; ERROR, RETURN - IN A,(IDECTRL) ; READ STATUS (FOR DELAY) - ; - RET ; - -;__SETUPDRIVE__________________________________________________________________________________________________________________________ -; -; SETUP FLOPPY DRIVE SETTINGS -;________________________________________________________________________________________________________________________________ -; -SETUPDRIVE: - LD A,#RESETL ; RESET SETTINGS -.IF COND144FLOPPY-1 - OR #MINI ; SELECT MINI FLOPPY (LOW DENS=1, HIGH DENS=0) 2/1/2013 -.ENDIF - OR #PRECOMP ; SELECT PRECOMP - OR #FDDENSITY ; SELECT DENSITY - OR #FDREADY ; SELECT READY SIGNAL - LD (FLATCH_STORE),A ; SAVE SETTINGS - LD A,#1 ; - LD (UNIT),A ; SET UNIT 1 - LD A,#2 ; DENSITY - LD (DENS),A ; - LD A,#9 ; -.IF COND144FLOPPY - ADD A,A -.ENDIF - LD (EOTSEC),A ; LAST SECTOR OF TRACK - LD A,#0x7F ; - LD (SRTHUT),A ; STEP RATE AND HEAD UNLOAD TIME - LD A,#5 ; - LD (HLT),A ; HEAD LOAD TIME - LD A,#0x0D ; - LD (GAP),A ; GAP -;; LD A,#0x80 ; -;; LD (SECSIZ),A ; SECTOR SIZE /4 - ; - CALL CHECKINT ; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR - CALL CHECKINT ; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR - CALL CHECKINT ; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR - CALL CHECKINT ; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR - CALL CHECKINT ; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR - CALL CHECKINT ; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR - ; - LD HL,#FLATCH_STORE ; POINT TO FLATCH - RES 1,(HL) ; SET MOTOR ON - CALL OUTFLATCH ; OUTPUT TO CONTROLLER - NOP ; - NOP ; - LD A,#0 ; ZERO TRACK - LD (PTRACK),A ; STORE TRACK - CALL SETTRACK ; DO IT - NOP ; - NOP ; - LD HL,#FLATCH_STORE ; POINT TO FLATCH - SET 1,(HL) ; SET MOTOR OFF - CALL OUTFLATCH ; OUTPUT TO CONTROLLER - RET -; -;__OUTFLATCH__________________________________________________________________________________________________________________________ -; -; SEND SETTINGS TO FLOPPY CONTROLLER -;________________________________________________________________________________________________________________________________ -; -OUTFLATCH: - LD A,(FLATCH_STORE) ; SET A TO SETTINGS - OUT (FLATCH),A ; OUTPUT TO CONTROLLER - RET - -;__FLOPPYREAD__________________________________________________________________________________________________________________________ -; -; READ A FLOPPY DISK SECTOR -;________________________________________________________________________________________________________________________________ -; -FLOPPYREAD: - .IF CONDUSEDSKY - CALL SEGDISPLAY ; - .ENDIF - LD A,#0x46 ; BIT 6 SETS MFM, 06H IS READ COMMAND - LD (CMD),A ; - JP DSKOP ; -; -;__FLOPPYWRITE__________________________________________________________________________________________________________________________ -; -; WRITE A FLOPPY DISK SECTOR -;________________________________________________________________________________________________________________________________ -; -FLOPPYWRITE: - .IF CONDUSEDSKY - CALL SEGDISPLAY ; - .ENDIF - LD A,#0x45 ; BIT 6 SETS MFM, 05H IS WRITE COMMAND - LD (CMD),A ; - JP DSKOP ; -; -;__DSKOP__________________________________________________________________________________________________________________________ -; -; PERFORM A DISK OPERATION -;________________________________________________________________________________________________________________________________ -; -DSKOP: - LD HL,#FLATCH_STORE ; POINT TO FLATCH - SET 1,(HL) ; SET MOTOR OFF - CALL OUTFLATCH ; OUTPUT TO CONTROLLER - ; - CALL CHECKINT ; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR - CP #0x0FF ; DID IT RETURN WITH ERROR CODE? - JP Z,DSKEXIT ; IF YES, EXIT WITH ERROR CODE - ; - LD A,(UNIT) ; GET DISK UNIT NUMBER - AND #3 ; MASK FOR FOUR DRIVES - LD B,A ; PARK IT IN B - LD A,(HEAD) ; GET HEAD SELECTION - AND #1 ; INSURE SINGLE BIT - RLA ; - RLA ; MOVE HEAD TO BIT 2 POSITION - OR B ; OR HEAD TO UNIT BYTE IN COMMAND BLOCK - LD (UNIT),A ; STORE IN UNIT - ; - LD HL,#FLATCH_STORE ; POINT TO FLATCH - RES 1,(HL) ; SET MOTOR ON - CALL OUTFLATCH ; OUTPUT TO CONTROLLER - ; - LD A,#3 ; SPECIFY COMMAND - CALL PFDATA ; PUSH IT - LD A,(SRTHUT) ; STEP RATE AND HEAD UNLOAD TIME - CALL PFDATA ; PUSH THAT - LD A,(HLT) ; - CALL PFDATA ; PUSH THAT - ; - CALL SETTRACK ; PERFORM SEEK TO TRACK - ; - JP NZ,DSKEXIT ; IF ERROR, EXIT - ; - LD A,(CMD) ; WHAT COMMAND IS PENDING? - OR A ; SET FLAGS - JP DOSO4 ; NO, MUST BE READ OR WRITE COMMAND -DSKEXIT: - LD HL,#FLATCH_STORE ; POINT TO FLATCH - SET 1,(HL) ; SET MOTOR OFF - CALL OUTFLATCH ; OUTPUT TO CONTROLLER - ; - OR #0x0FF ; SET -1 IF ERROR - RET - -RESULT: - LD C,#7 ; LOAD C WITH NUMBER OF STATUS BYTES - LD HL,#ST0 ; POINT TO STATS STORAGE -RS3: - CALL GFDATA ; GET FIRST BYTE - LD (HL),A ; SAVE IT - INC HL ; POINTER++ - DEC C ; CC-1 - JP NZ,RS3 ; LOOP TIL C0 - LD A,(ST0) ; LOAD STS0 - AND #0x0F8 ; MASK OFF DRIVE # - LD B,A ; PARK IT - LD A,(ST1) ; LOAD STS1 - OR B ; ACC OR B ->ACC IF 0 THEN SUCCESS - ; -RSTEXIT: - CALL CHECKINT ; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR - LD HL,#FLATCH_STORE ; POINT TO FLATCH - SET 1,(HL) ; SET MOTOR OFF - CALL OUTFLATCH ; OUTPUT TO CONTROLLER - ; - .IF CONDUSEDSKY - CALL SEGDISPLAY ; - .ENDIF - RET ; DONE RETURN TO CALLER - - -DOSO4: - ; -.IF 1 ; -INT_LOC = 0x038 ; IM 1 INTERRUPT CALLS GO HERE -; SET UP FOR I/O AT INTERRUPT LEVEL - LD DE,#INT_LOC - LD HL,#INT_RD - LD BC,#L_INT_RD - LD A,(CMD) ; - AND #0b000000001 ; WRITE IS 1 - JP Z,IS_READ - ADD HL,BC -IS_READ: - LDIR -.ENDIF - - LD HL,#SECTOR_BUFFER ; GET BUFFER ADDRESS TO HL -;; LD A,(SECSIZ) ; XFERLEN -;; LD C,A ; C WILL BE THE NUMBER OF TRANSACTIONS - ; DIVIDED BY 4 - - ld de,(FSECSIZ) ; GET FULL SECTOR SIZE - LD B,E - LD C,#FDATA ; GET DATA REGISTER I/O ADDRESS - - LD A,(CMD) ; - CALL PFDATA ; PUSH COMMAND TO I8272 - LD A,(UNIT) ; - CALL PFDATA ; - LD A,(PTRACK) ; - CALL PFDATA ; - LD A,(HEAD) ; - CALL PFDATA ; - LD A,(PSECTOR) ; - INC A ; - CALL PFDATA ; - LD A,(DENS) ; - CALL PFDATA ; WHAT DENSITY - LD A,(EOTSEC) ; - CALL PFDATA ; ASSUME SC (SECTOR COUNT) EOT - LD A,(GAP) ; - CALL PFDATA ; WHAT GAP IS NEEDED - LD A,(DTL) ; DTL, IS THE LAST COMMAND BYTE TO I8272 - CALL PFDATAS ; -; -; -; PERFORM READ / WRITE -; - - -RDD_POLL: - -FDC_RW_P0: - EI - HALT - JP NZ,FDC_RW_P0 ;10 COUNT THRU 256 BYTES -FDC_RW_P1: - EI - HALT - JP NZ,FDC_RW_P1 ;10 COUNT THRU 256 BYTES - - -; FALL THROUGH WITH INTERRUPTS DISABLED (NOT ENABLED IN INTERRUPT SERVICE) - - -DSKOPEND: - LD HL,#FLATCH_STORE ; POINT TO FLATCH - SET 0,(HL) ; SET TC - CALL OUTFLATCH ; OUTPUT TO CONTROLLER - NOP ; - NOP ; 2 MICROSECOND DELAY - RES 0,(HL) ; RESET TC - CALL OUTFLATCH ; OUTPUT TO CONTROLLER - NOP ; - NOP ; 2 MICROSECOND DELAY - NOP ; - NOP ; 2 MICROSECOND DELAY - SET 1,(HL) ; TURN OFF MOTOR - CALL OUTFLATCH ; OUTPUT TO CONTROLLER - JP RESULT ; GET STATUS BYTES - - - -INT_RD: INI - RET -IRTEMP: -L_INT_RD = IRTEMP - INT_RD - -INT_WR: OUTI - RET -IWTEMP: -L_INT_WR = IWTEMP - INT_WR - - - -;__SETTRACK__________________________________________________________________________________________________________________________ -; -; SEEK TO A TRACK ON GIVEN UNIT -; A: TRACK # -;________________________________________________________________________________________________________________________________ -; -SETTRACK: - LD A,(FTRACK) ; GET CURRENT HEAD TRACK - LD C,A - LD A,(PTRACK) ; GET TRACK - OR A ; SET FLAGS - JP Z,RECAL ; IF 0 PERFORM RECAL INSTEAD OF SEEK - CP C ; - JP Z,WAINT ; ALREADY THERE, ABORT - LD (FTRACK),A ; STORE TRACK - LD A,#0x0F ; SEEK COMMAND - CALL PFDATA ; PUSH COMMAND - LD A,(UNIT) ; SAY WHICH UNIT - CALL PFDATA ; SEND THAT - LD A,(PTRACK) ; TO WHAT TRACK - CALL PFDATA ; SEND THAT TOO - JP WAINT ; WAIT FOR INTERRUPT SAYING DONE -RECAL: - LD A,#0 ; - LD (FTRACK),A ; STORE TRACK - LD A,#7 ; RECAL TO TRACK 0 - CALL PFDATA ; SEND IT - LD A,(UNIT) ; WHICH UNIT - CALL PFDATA ; SEND THAT TOO - ; -WAINT: - ; - CALL DELAYHSEC ; DELAY TO LET HEADS SETTLE BEFORE READ - ; - ; WAIT HERE FOR INTERRPT SAYING DONE - ; LOOP TIL INTERRUPT - CALL CHECKINT ; CHECK INTERRUPT STATUS - ; - RET - -;__CYCLEFLOPPY__________________________________________________________________________________________________________________________ -; -; SEEK TO TRACK 0, THEN BACK TO THE SELECTED TRACK -; THIS CAN BE USED ON AN ERROR CONDITION TO VERIFY THAT HEAD IS ON SELECTED TRACK -; -;________________________________________________________________________________________________________________________________ -; -CYCLEFLOPPY: - PUSH AF ; STORE AF - PUSH HL ; STORE HL - CALL CHECKINT ; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR - CALL CHECKINT ; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR - CALL CHECKINT ; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR - CALL CHECKINT ; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR - CALL CHECKINT ; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR - CALL CHECKINT ; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR - LD HL,#FLATCH_STORE ; POINT TO FLATCH - RES 1,(HL) ; SET MOTOR ON - CALL OUTFLATCH ; OUTPUT TO CONTROLLER - NOP ; - NOP ; - CALL RECAL ; - CALL DELAYHSEC ; - CALL DELAYHSEC ; - CALL DELAYHSEC ; - CALL DELAYHSEC ; - CALL RECAL ; - CALL DELAYHSEC ; - CALL DELAYHSEC ; - CALL DELAYHSEC ; - CALL DELAYHSEC ; - CALL SETTRACK ; - CALL DELAYHSEC ; - CALL DELAYHSEC ; - CALL DELAYHSEC ; - CALL DELAYHSEC ; - POP HL ; - POP AF ; RESTORE AF - RET - -;__PFDATAS__________________________________________________________________________________________________________________________ -; -; WRITE A COMMAND OR PARAMETER SEQUENCE -; -; TRANSFERS ARE SYNCHONIZED BYT MSR D7 AND D6 -; RQM DIO -; 0 0 BUSY -; 1 0 WRITE TO DATA REGISTER PERMITTED -; 1 1 BYTE FOR READ BY HOST PENDING -; 0 1 BUSY -; -;________________________________________________________________________________________________________________________________ -; -PFDATAS: - PUSH AF ; STORE AF -PFDS1: - IN A,(FMSR) ; READING OR WRITING IS KEYS TO D7 RQM - AND #0x80 ; MASK OFF RQM BIT - JP Z,PFDS1 ; WAIT FOR RQM TO BE TRUE - IN A,(FMSR) ; READ STATUS - AND #0x40 ; WAITING FOR INPUT? - CALL NZ,ERRORT ; NO, SIGNAL ERROR - POP AF ; RESTORE AF - OUT (FDATA),A ; OUTPUT A TO CONTROLLER - RET - -;__PFDATA__________________________________________________________________________________________________________________________ -; -; WRITE A COMMAND OR PARAMETER SEQUENCE -; -; TRANSFERS ARE SYNCHONIZED BYT MSR D7 AND D6 -; RQM DIO -; 0 0 BUSY -; 1 0 WRITE TO DATA REGISTER PERMITTED -; 1 1 BYTE FOR READ BY HOST PENDING -; 0 1 BUSY -; -;________________________________________________________________________________________________________________________________ -; -PFDATA: - PUSH AF ; STORE AF -PFD1: - IN A,(FMSR) ; READING OR WRITING IS KEYS TO D7 RQM - AND #0x80 ; MASK OFF RQM BIT - JP Z,PFD1 ; WAIT FOR RQM TO BE TRUE - IN A,(FMSR) ; READ STATUS - AND #0x40 ; WAITING FOR INPUT? - CALL NZ,ERRORT ; NO, SIGNAL ERROR - POP AF ; RESTORE AF - OUT (FDATA),A ; OUTPUT A TO CONTROLLER - JP DELAY24 ; DELAY 24US - - - -;__DELAY24__________________________________________________________________________________________________________________________ -; -; DELAY 24US -;________________________________________________________________________________________________________________________________ -; -DELAY24: - ; JP= 10T - PUSH IX ; 15T - POP IX ; 14T - PUSH IX ; 15T - POP IX ; 14T -DELAY12: - PUSH IX ; 15T - POP IX ; 14T - RET ; 10T - - -;__CHECKINT__________________________________________________________________________________________________________________________ -; -; CHECK FOR ACTIVE FDC INTERRUPTS BEFORE GIVING I8272 COMMANDS -; POLL RQM FOR WHEN NOT BUSY AND THEN SEND FDC -; SENSE INTERRUPT COMMAND IF IT RETURNS WITH NON ZERO -; ERROR CODE, PASS BACK TO CALLING ROUTINE FOR HANDLING -;________________________________________________________________________________________________________________________________ -; -CHECKINT: - IN A,(FMSR) ; READING OR WRITING IS KEYS TO D7 RQM - AND #0x80 ; MASK OFF RQM BIT - JP Z,CHECKINT ; WAIT FOR RQM TO BE TRUE WAIT UNTIL DONE - IN A,(FMSR) ; READ STATUS - AND #0x40 ; WAITING FOR INPUT? - JP NZ,CHECKINTDONE ; NO, SIGNAL ERROR - CALL SENDINT ; SENSE INTERRUPT COMMAND -CHECKINTDONE: - RET ; - - -;__DELAYHSEC__________________________________________________________________________________________________________________________ -; -; DELAY FOR 1/2 SECOND -;________________________________________________________________________________________________________________________________ -; -DELAYHSEC: - LD HL,#0 ; 65536 -DELDM: - NOP ; (4 T) - NOP ; (4 T) - NOP ; (4 T) - NOP ; (4 T) - DEC L ; (6 T) - JP NZ,DELDM ; (10 T) 24 T 8 MICROSECONDS AT 4 MHZ - DEC H ; (6 T) - JP NZ,DELDM ; (10 T) (8 US * 256) * 256 524288 US 5 SECONDS - RET - -;__ERRORT__________________________________________________________________________________________________________________________ -; -; ERROR HANDLING -;________________________________________________________________________________________________________________________________ -; -ERRORT: - IN A,(FDATA) ; CLEAR THE JUNK OUT OF DATA REGISTER - IN A,(FMSR) ; CHECK WITH RQM - AND #0x80 ; IF STILL NOT READY, READ OUT MORE JUNK - JP Z,ERRORT ; - LD A,#0x0FF ; RETURN ERROR CODE -1 - ; - RET - -;__SENDINT__________________________________________________________________________________________________________________________ -; -; SENSE INTERRUPT COMMAND -;________________________________________________________________________________________________________________________________ -; -SENDINT: - LD A,#8 ; SENSE INTERRUPT COMMAND - CALL PFDATA ; SEND IT - CALL GFDATA ; GET RESULTS - LD (ST0A),A ; STORE THAT - AND #0x0C0 ; MASK OFF INTERRUPT STATUS BITS - CP #0x80 ; CHECK IF INVALID COMMAND - JP Z,ENDSENDINT ; YES, EXIT - CALL GFDATA ; GET ANOTHER (STATUS CODE 1) - LD (ST1A),A ; SAVE THAT - LD A,(ST0A) ; GET FIRST ONE - AND #0x0C0 ; MASK OFF ALL BUT INTERRUPT CODE 00 IS NORMAL -ENDSENDINT: - RET ; ANYTHING ELSE IS AN ERROR - - -;__GFDATA__________________________________________________________________________________________________________________________ -; -; GET DATA FROM FLOPPY CONTROLLER -; -; TRANSFERS ARE SYNCHONIZED BYT MSR D7 AND D6 -; RQM DIO -; 0 0 BUSY -; 1 0 WRITE TO DATA REGISTER PERMITTED -; 1 1 BYTE FOR READ BY HOST PENDING -; 0 1 BUSY -; -;________________________________________________________________________________________________________________________________ -; -GFDATA: - IN A,(FMSR) ; READ STATUS BYTE - AND #0x80 ; MASK OFF RQM - JP Z,GFDATA ; LOOP WHILE BUSY - IN A,(FMSR) ; READ STSTUS BUTE - AND #0x40 ; MASK OFF DIO - CALL Z,ERRORT ; IF WRITE EXPECTED RUN ERRORRT - IN A,(FDATA) ; READ DATA - JP DELAY24 ; DELAY 24US - - - - .IF CONDUSEDSKY -;__IDESEGDISPLAY________________________________________________________________________________________ -; -; DISPLAY CONTENTS OF IDE LOGICAL BLOCK ADDRESS ON DSKY -;____________________________________________________________________________________________________ -IDESEGDISPLAY: - LD A, #0x82 ; - OUT (PIOCONT),A ; - ; - LD A,(IDE_LBA3) ; - AND #0x0F ; - LD (DISPLAYBUF+6),A ; - LD A,(IDE_LBA3) ; - AND #0x0F0 ; - SRL A ; - SRL A ; - SRL A ; - SRL A ; - LD (DISPLAYBUF+7),A ; - ; - LD A,(IDE_LBA2) ; - AND #0x0F ; - LD (DISPLAYBUF+4),A ; - LD A,(IDE_LBA2) ; - AND #0x0F0 ; - SRL A ; - SRL A ; - SRL A ; - SRL A ; - LD (DISPLAYBUF+5),A ; - ; - LD A,(IDE_LBA1) ; - AND #0x0F ; - LD (DISPLAYBUF+2),A ; - LD A,(IDE_LBA1) ; - AND #0x0F0 ; - SRL A ; - SRL A ; - SRL A ; - SRL A ; - LD (DISPLAYBUF+3),A ; - - LD A,(IDE_LBA0) ; - AND #0x0F ; - LD (DISPLAYBUF),A ; - LD A,(IDE_LBA0) ; - AND #0x0F0 ; - SRL A ; - SRL A ; - SRL A ; - SRL A ; - LD (DISPLAYBUF+1),A ; - JP SEGDISPLAY1 ; - -;__ATAPISEGDISPLAY________________________________________________________________________________________ -; -; DISPLAY CONTENTS OF ATAPI LOGICAL BLOCK ADDRESS ON DSKY -;____________________________________________________________________________________________________ -ATAPISEGDISPLAY: - LD A, #0x82 ; - OUT (PIOCONT),A ; - ; - LD A,(LBA_TARGET_HI+1) ; - AND #0x0F ; - LD (DISPLAYBUF+6),A ; - LD A,(LBA_TARGET_HI+1) ; - AND #0x0F0 ; - SRL A ; - SRL A ; - SRL A ; - SRL A ; - LD (DISPLAYBUF+7),A ; - ; - LD A,(LBA_TARGET_HI) ; - AND #0x0F ; - LD (DISPLAYBUF+4),A ; - LD A,(LBA_TARGET_HI) ; - AND #0x0F0 ; - SRL A ; - SRL A ; - SRL A ; - SRL A ; - LD (DISPLAYBUF+5),A ; - ; - LD A,(LBA_TARGET_LO+1) ; - AND #0x0F ; - LD (DISPLAYBUF+2),A ; - LD A,(LBA_TARGET_LO+1) ; - AND #0x0F0 ; - SRL A ; - SRL A ; - SRL A ; - SRL A ; - LD (DISPLAYBUF+3),A ; - ; - LD A,(LBA_TARGET_LO) ; - AND #0x0F ; - LD (DISPLAYBUF),A ; - LD A,(LBA_TARGET_LO) ; - AND #0x0F0 ; - SRL A ; - SRL A ; - SRL A ; - SRL A ; - LD (DISPLAYBUF+1),A ; - JP SEGDISPLAY1 ; - -;__SEGDISPLAY________________________________________________________________________________________ -; -; DISPLAY CONTENTS OF TRACK, SECTOR, ST0, ST1 ON DSKY -; -;____________________________________________________________________________________________________ -SEGDISPLAY: - LD A, #0x82 ; - OUT (PIOCONT),A ; - LD A,(TRACK) ; - AND #0x0F ; - LD (DISPLAYBUF+6),A ; - LD A,(TRACK) ; - AND #0x0F0 ; - SRL A ; - SRL A ; - SRL A ; - SRL A ; - LD (DISPLAYBUF+7),A ; - LD A,(SECTOR) ; - AND #0x0F ; - LD (DISPLAYBUF+4),A ; - LD A,(SECTOR) ; - AND #0x0F0 ; - SRL A ; - SRL A ; - SRL A ; - SRL A ; - LD (DISPLAYBUF+5),A ; - LD A,(ST0) ; - AND #0x0F ; - LD (DISPLAYBUF+2),A ; - LD A,(ST0) ; - AND #0x0F0 ; - SRL A ; - SRL A ; - SRL A ; - SRL A ; - LD (DISPLAYBUF+3),A ; - LD A,(ST1) ; - AND #0x0F ; - LD (DISPLAYBUF),A ; - LD A,(ST1) ; - AND #0x0F0 ; - SRL A ; - SRL A ; - SRL A ; - SRL A ; - LD (DISPLAYBUF+1),A ; -SEGDISPLAY1: ; - LD HL,#DISPLAYBUF ; - LD BC,#7 ; - ADD HL,BC ; - LD B,#8 ; SET DIGIT COUNT - LD A,#0x40 ; SET CONTROL PORT 7218 TO OFF - OUT (PORTC),A ; OUTPUT - CALL DELAY12 ; WAIT - LD A,#0x0D0 ; SET CONTROL TO 1111 (DATA COMING, HEX DECODE, DECODE, NORMAL) - OUT (PORTA),A ; OUTPUT TO PORT - LD A,#0x80 ; STROBE WRITE PULSE WITH CONTROL=1 - OUT (PORTC),A ; OUTPUT TO PORT - CALL DELAY12 ; WAIT - LD A,#0x40 ; SET CONTROL PORT 7218 TO OFF - OUT (PORTC),A ; OUTPUT - CALL DELAY12 ; WAIT -SEGDISPLAY_LP: - LD A,(HL) ; GET DISPLAY DIGIT - OUT (PORTA),A ; OUT TO PORTA - LD A,#0 ; SET WRITE STROBE - OUT (PORTC),A ; OUT TO PORTC - CALL DELAY12 ; DELAY - LD A,#0x40 ; SET CONTROL PORT OFF - OUT (PORTC),A ; OUT TO PORTC - CALL DELAY12 ; WAIT - DEC HL ; INC POINTER - DJNZ SEGDISPLAY_LP ; LOOP FOR NEXT DIGIT - RET - -DISPLAYBUF: .DB 01,02,03,04,05,06,07,08 - .ENDIF - .DB 00,00,00,00,00,00,00,00 - .DB 00,00,00,00,00,00,00,00 - .DB 00,00,00,00,00,00,00,00 - .DB 00,00,00,00,00,00,00,00 - - - -FLOPPYSTACK: .DB 00 -PARKSTACK: .DB 00,00,00,00 - -READ_DISK_PACKET: - .DB 0x0A8,00,00,00,00,01,00,00,00,01,00,00 -WRITE_DISK_PACKET: - .DB 0x2A,00,00,00,00,0x11,00,00,01,00,00,00 -ATAPI_REQUEST_SENSE: - .DB 3,00,00,00,0x11,00,00,00,00,00,00,00 - -; ******* TEXT STRINGS ******* - -TXT_RO_ERROR: - .DB CR,LF - .ascii "ERROR: WRITE TO READ ONLY DISK" - .DB END - - -TXT_STARTUP_MSG: - - .IF CONDSHORTMSG - .DB CR,LF - .ascii "CP/M-80 2.2C (JC0705-1) for " - .ascii "N8VEM - W/" - .IF CONDUSEVDU - .ascii "VDU " - .ENDIF - .IF CONDUSEDSKY - .ascii "DSKY " - .ENDIF - .IF CONDIDESOFT - .ascii "IDE " - .ENDIF - .IF CONDUSEATAPI - .ascii "ATAPI " - .ENDIF - .IF CONDUSEFLOPPY - .ascii "FLOPPY " - .IF COND144FLOPPY - .ascii "1.44M " - .ENDIF - .ENDIF - .DB CR,LF - .DB END - .ELSE - .ascii "CP/M V2.2C" - .DB END - .ENDIF - -; -; THE REMAINDER OF THE CBIOS IS RESERVED UNINITIALIZED -; DATA AREA, AND DOES NOT NEED TO BE A PART OF THE -; SYSTEM MEMORY IMAGE (THE SPACE MUST BE AVAILABLE, -; HOWEVER, BETWEEN "BEGDAT" AND "ENDDAT") -; - -; -; DISK COMMAND BLOCK -; -CMD: .DB 0 ; COMMAND READ OR WRITE, -UNIT: .DB 0 ; PHYSICAL DRIVE 0->3 -HEAD: .DB 0 ; HEAD SEL 0 OR 1 -DENS: .DB 2 ; DENSITY -EOTSEC: .DB 09 ; LAST SECTOR OF TRACK -GAP: .DB 0x1B ; VALUE FOR IRG -;SECSIZ: .DB 0x80 ; HOW MANY BYTES TO TRANSFER/4 -FSECSIZ: .dw 0x0200 ; actual sector size in bytes -DTL: .DB 0x0FF ; SIZE OF SECTOR -SRTHUT: .DB 0x7F ; STEP RATE AND HEAD UNLOAD TIME -HLT: .DB 5 ; HEAD LOAD TIME -MIN: .DB MINI ; LATCH BIT PATTERN FOR FDC9229 MINITRUE -PRE: .DB PRECOMP ; LATCH BIT PATTERN FOR FDC9229 PRECOMP125NS -; -; FLOPPY STATUS RESULT STORAGE -; -ST0: .DB 0 ; STORE STATUS 0 -ST1: .DB 0 ; ST1 -ST2: .DB 0 ; ST2 -SCYL: .DB 0 ; TRACK -SHEAD: .DB 0 ; HEAD 0 OR 1 -SREC: .DB 0 ; SECTOR -SNBIT: .DB 0 ; DENSITY -ST0A: .DB 0 ; STORE STATUS 0 -ST1A: .DB 0 ; ST1 -RETRY: .DB 0 ; RETRIES -RETRY1: .DB 0 ; RETRIES - -FLATCH_STORE: .DB 00 ; - -TRACK: .DW 0 ; TWO BYTES FOR TRACK # (LOGICAL) -PTRACK: .DW 0 ; TWO BYTES FOR TRACK # (PHYSICAL) -FTRACK: .DW 0 ; TWO BYTES FOR TRACK # (HEAD LOCATION) - -PAGER: .DB 1 ; COPY OF PAGER BYTE -DB_PAGER: .DB 0x0FF ; COPY OF PAGER BYTE (DEBUG) -SECTOR: .DW 0 ; TWO BYTES FOR SECTOR # (LOGICAL) -PSECTOR: .DW 0 ; TWO BYTES FOR SECTOR # (PHYSICAL) -SECST: .DW 0 ; SECTOR IN ROM/RAM START ADDRESS -DMAAD: .DW 0 ; DIRECT MEMORY ADDRESS -DISKNO: .DB 0 ; DISK NUMBER 0-15 -LBA_TARGET_LO: .DW 0 ; IDE HD PARTITION TARGET SECTOR (LOW 16 BITS) -LBA_TARGET_HI: .DW 0 ; IDE HD PARTITION TARGET SECTOR (HI 16 BITS, 12 USED) -IDEDEVICE: .DB 0 ; ATAPI DEVICE SELECTION FLAG - -IDE_LBA0: .DB 0 ; SET LBA 0:7 -IDE_LBA1: .DB 0 ; SET LBA 8:15 -IDE_LBA2: .DB 0 ; SET LBA 16:23 -IDE_LBA3: .DB 0 ; LOWEST 4 BITS USED ONLY TO ENABLE LBA MODE -SECTOR_INDEX: .DB 1 ; WHERE 128 BYTE CP/M SECTOR IS IN 512 BYTE IDE HD SECTOR -; -; SCRATCH RAM AREA FOR BDOS USE -BEGDAT: -; = $ ; BEGINNING OF DATA AREA -DIRBF: .DS 128 ; SCRATCH DIRECTORY AREA -ALL00: .DS 65 ; ALLOCATION VECTOR 0 (DSM/8 = 1 BIT PER BLOCK) 44 -ALL01: .DS 33 ; ALLOCATION VECTOR 1 (225/8) -ALL02: .DS 256 ; ALLOCATION VECTOR 2 (511/8) -ALL03: .DS 256 ; ALLOCATION VECTOR 3 (511/8) -ALL04: .DS 65 ; ALLOCATION VECTOR 4 (497/8) -ALL05: .DS 65 ; ALLOCATION VECTOR 4 (495/8) -ALL06: .DS 65 ; ALLOCATION VECTOR 4 (495/8) -ALL07: .DS 135 ; ALLOCATION VECTOR 7 (495/8) -CHK00: .DS 5 ; 720K MEDIA -CHK01: .DS 0 ; NOT USED FOR FIXED MEDIA -CHK02: .DS 0 ; NOT USED FOR FIXED MEDIA -CHK03: .DS 128 ; 8M MEDIA -CHK04: .DS 0 ; NOT USED FOR FIXED MEDIA -CHK05: .DS 0 ; NOT USED FOR FIXED MEDIA -CHK06: .DS 0 ; NOT USED FOR FIXED MEDIA -CHK07: .DS 15 ; 1.44M MEDIA -; -CUDISK: .DS 1 ; CURRENT PHYSICAL DISK ID IN BUFFER -CUSECTOR: .DW 1 ; CURRENT PHYSICAL DISK SECTOR IN BUFFER -CUTRACK: .DW 2 ; CURRENT PHYSICAL DISK TRACK IN BUFFER -SECTOR_BUFFER: .DS 520 ; STORAGE FOR 512 BYTE IDE HD SECTOR -ENDDAT: -; .EQU $ ; END OF DATA AREA -DSTEMP: -DATSIZ = DSTEMP - BEGDAT ; SIZE OF DATA AREA - - -;dwg; .ORG 0FDFFH -LASTBYTE: .DB 0 - -; .END - - - - - -_cbios_end:: - .area _CODE - .area _CABS diff --git a/doug/src/cbios.sym b/doug/src/cbios.sym deleted file mode 100755 index dd03f558..00000000 --- a/doug/src/cbios.sym +++ /dev/null @@ -1,137 +0,0 @@ - ASxxxx Assembler V02.00 + NoICE + SDCC mods + Flat24 (Zilog Z80 / Hitachi HD64180), page 1. -cbios.s derived from cbios.asm -Symbol Table - - .__.ABS.= 0000 G | 6 AL0_0 00AC R | 6 AL0_1 00BB R - 6 AL0_2 00CA R | 6 AL0_3 00D9 R | 6 AL0_4 00E8 R - 6 AL0_5 00F7 R | 6 AL0_6 0106 R | 6 AL0_7 0115 R - 6 AL1_0 00AD R | 6 AL1_1 00BC R | 6 AL1_2 00CB R - 6 AL1_3 00DA R | 6 AL1_4 00E9 R | 6 AL1_5 00F8 R - 6 AL1_6 0107 R | 6 AL1_7 0116 R | 6 ALL00 0B9D R - 6 ALL01 0BDE R | 6 ALL02 0BFF R | 6 ALL03 0CFF R - 6 ALL04 0DFF R | 6 ALL05 0E40 R | 6 ALL06 0E81 R - 6 ALL07 0EC2 R | 6 ATAPI_DE 06D7 R | 6 ATAPI_DL 05D4 R - 6 ATAPI_RE 0728 R | 6 ATAPI_RE 0718 R | 6 ATAPI_RE 06DF R - 6 ATAPI_RE 0A80 R | 6 ATAPI_SE 077D R | 6 ATAPI_SE 07AA R - 6 ATAPI_SO 069F R | 6 ATAPI_TO 05E3 R | 6 ATAPI_WA 05CF R - 6 ATAPI_WB 05D2 R | 6 ATAPI_WR 0767 R | 6 ATAPI_WR 073C R - BDOS = D806 | 6 BEGDAT 0B1D R | BIAS = 9C00 - BIOS = E600 | 6 BLKSEC 02C0 R | 6 BLM_0 00A6 R - 6 BLM_1 00B5 R | 6 BLM_2 00C4 R | 6 BLM_3 00D3 R - 6 BLM_4 00E2 R | 6 BLM_5 00F1 R | 6 BLM_6 0100 R - 6 BLM_7 010F R | 6 BOOT 011B R | 6 BSH_0 00A5 R - 6 BSH_1 00B4 R | 6 BSH_2 00C3 R | 6 BSH_3 00D2 R - 6 BSH_4 00E1 R | 6 BSH_5 00F0 R | 6 BSH_6 00FF R - 6 BSH_7 010E R | CCP = D000 | CCPSIZ_C= 0800 - CDISK = 0004 | CHARIN = 011B | 6 CHECKINT 09E4 R - 6 CHECKINT 09F5 R | 6 CHK00 0F49 R | 6 CHK01 0F4E R - 6 CHK02 0F4E R | 6 CHK03 0F4E R | 6 CHK04 0FCE R - 6 CHK05 0FCE R | 6 CHK06 0FCE R | 6 CHK07 0FCE R - 6 CKS_0 00AE R | 6 CKS_1 00BD R | 6 CKS_2 00CC R - 6 CKS_3 00DB R | 6 CKS_4 00EA R | 6 CKS_5 00F9 R - 6 CKS_6 0108 R | 6 CKS_7 0117 R | 6 CMD 0AE9 R - COND144F= 0001 | CONDABON= 0001 | CONDIDES= 0001 - CONDSHOR= 0001 | CONDSUPE= 0001 | CONDUSEA= 0000 - CONDUSED= 0000 | CONDUSEF= 0001 | CONDUSEV= 0000 - 6 CONIN 01A6 R | 6 CONOUT 01B1 R | 6 CONST 019C R - 6 CONVERT_ 0516 R | 6 COPY_CPM 0510 R | CR = 000D - 6 CUDISK 0FDD R | 6 CUSECTOR 0FDE R | 6 CUTRACK 0FE0 R - 6 CYCLEFLO 0961 R | DATSIZ = 06CD | 6 DB_PAGER 0B09 R - 6 DEBSEC 02A8 R | 6 DELAY12 09DF R | 6 DELAY24 09D7 R - 6 DELAYHSE 09F6 R | 6 DELDM 09F9 R | 6 DENS 0AEC R - 6 DIRBF 0B1D R | 6 DISKNO 0B12 R | 6 DMAAD 0B10 R - 6 DOSO4 08A4 R | 6 DPBASE 0033 R | 6 DPBLK0 00A3 R - 6 DPBLK1 00B2 R | 6 DPBLK2 00C1 R | 6 DPBLK3 00D0 R - 6 DPBLK4 00DF R | 6 DPBLK5 00EE R | 6 DPBLK6 00FD R - 6 DPBLK7 010C R | 6 DRM_0 00AA R | 6 DRM_1 00B9 R - 6 DRM_2 00C8 R | 6 DRM_3 00D7 R | 6 DRM_4 00E6 R - 6 DRM_5 00F5 R | 6 DRM_6 0104 R | 6 DRM_7 0113 R - 6 DSKEXIT 0875 R | 6 DSKOP 082E R | 6 DSKOPEND 0903 R - 6 DSM_0 00A8 R | 6 DSM_1 00B7 R | 6 DSM_2 00C6 R - 6 DSM_3 00D5 R | 6 DSM_4 00E4 R | 6 DSM_5 00F3 R - 6 DSM_6 0102 R | 6 DSM_7 0111 R | 6 DSTEMP 11EA R - 6 DTL 0AF1 R | END = 00FF | 6 ENDDAT 11EA R - 6 ENDSENDI 0A2F R | 6 EOTSEC 0AED R | 6 ERRORT 0A06 R - 6 EXM_0 00A7 R | 6 EXM_1 00B6 R | 6 EXM_2 00C5 R - 6 EXM_3 00D4 R | 6 EXM_4 00E3 R | 6 EXM_5 00F2 R - 6 EXM_6 0101 R | 6 EXM_7 0110 R | FALSE = 0000 - FDATA = 0037 | 6 FDC_RW_P 08F9 R | 6 FDC_RW_P 08FE R - FDDENSIT= 0040 | FDMA = 003C | FDREADY = 0080 - FLATCH = 003A | 6 FLATCH_S 0B01 R | 6 FLOPPYRE 081E R - 6 FLOPPYST 0A63 R | 6 FLOPPYWR 0826 R | FMSR = 0036 - 6 FSECSIZ 0AEF R | 6 FTRACK 0B06 R | 6 GAP 0AEE R - GET_KEY = 039C | 6 GFDATA 0A30 R | 6 GOCPM 0167 R - 6 HEAD 0AEB R | 6 HLT 0AF3 R | 6 HOME 01DA R - IDEADDR = 002F | 6 IDEBUFRD 0642 R | 6 IDEBUFWT 0656 R - IDECTRL = 002E | IDECYLHI= 0025 | IDECYLLO= 0024 - 6 IDEDEVIC 0B17 R | IDEERR = 0021 | IDEHEAD = 0026 - IDEHI = 0028 | IDELO = 0020 | IDESECTC= 0022 - IDESECTN= 0023 | IDESTTS = 0027 | 6 IDE_BLP 0627 R - 6 IDE_DLP 05F8 R | 6 IDE_ERR 0620 R | 6 IDE_LBA0 0B18 R - 6 IDE_LBA1 0B19 R | 6 IDE_LBA2 0B1A R | 6 IDE_LBA3 0B1B R - 6 IDE_READ 063C R | 6 IDE_READ 056A R | 6 IDE_READ 058B R - 6 IDE_SETU 0666 R | 6 IDE_SOFT 05C3 R | 6 IDE_SREX 057B R - 6 IDE_TEST 060F R | 6 IDE_TO 060D R | 6 IDE_TO2 063A R - 6 IDE_WAIT 0622 R | 6 IDE_WAIT 05F3 R | 6 IDE_WAIT 05E5 R - 6 IDE_WAIT 05EC R | 6 IDE_WBSY 05F6 R | 6 IDE_WDRQ 0625 R - 6 IDE_WRIT 0650 R | 6 IDE_WRIT 059F R | INT_LOC = 0038 - 6 INT_RD 091E R | 6 INT_WR 0921 R | IOBYTE = 0003 - 6 IRTEMP 0921 R | 6 ISCUR 02DC R | IS_KBHIT= 0395 - 6 IS_READ 08B6 R | 6 IWTEMP 0924 R | 6 LASTBYTE 11EA R - 6 LBA_TARG 0B15 R | 6 LBA_TARG 0B13 R | LF = 000A - 6 LIST 01BC R | 6 LISTST 01BE R | L_INT_RD= 0003 - L_INT_WR= 0003 | 6 MIN 0AF4 R | MINI = 0004 - MOTOR = 0000 | MOVSIZ_C= 2BFF | MPCL_RAM= 0078 - MPCL_ROM= 007C | MSIZE = 003B | 6 NOT_READ 01A5 R - 6 OFF_0 00B0 R | 6 OFF_1 00BF R | 6 OFF_2 00CE R - 6 OFF_3 00DD R | 6 OFF_4 00EC R | 6 OFF_5 00FB R - 6 OFF_6 010A R | 6 OFF_7 0119 R | 6 OUTFLATC 0818 R - 6 PAGER 0B08 R | 6 PAGERB 04D9 R | 6 PARKSTAC 0A64 R - 6 PFD1 09C3 R | 6 PFDATA 09C2 R | 6 PFDATAS 09AF R - 6 PFDS1 09B0 R | PIOCONT = 0063 | PORTA = 0060 - PORTB = 0061 | PORTC = 0062 | 6 PRE 0AF5 R - PRECOMP = 0020 | 6 PRTMSG 04BC R | 6 PRTMSG1 04CA R - PR_OUTCH= 0CD6 | 6 PSECTOR 0B0C R | 6 PTRACK 0B04 R - 6 PUNCH 01C0 R | RAMTARG_= D000 | 6 RDD_POLL 08F9 R - 6 RDONLY 03F4 R | 6 READ 01F2 R | 6 READER 01C2 R - 6 READ_ATA 039D R | 6 READ_ATA 03C5 R | 6 READ_ATA 03A2 R - 6 READ_DIS 0A68 R | 6 READ_EEP 0214 R | 6 READ_FLP 02FE R - 6 READ_FLP 0315 R | 6 READ_FLP 031A R | 6 READ_FLP 0365 R - 6 READ_FLP 032F R | 6 READ_HDP 03D6 R | 6 READ_IDE 0378 R - 6 READ_IDE 0396 R | 6 READ_RAM 025A R | 6 RECAL 094A R - 6 REQUEST_ 06B8 R | 6 REQUEST_ 06C4 R | RESETL = 0002 - 6 RESULT 0880 R | 6 RETRY 0AFF R | 6 RETRY1 0B00 R - 6 ROMD 04F3 R | ROMSTART= 0A00 | 6 RPAGE 0504 R - 6 RRA16 0561 R | 6 RS3 0885 R | 6 RSTEXIT 0898 R - 6 SCYL 0AF9 R | 6 SECPAGE 04CB R | 6 SECST 0B0E R - 6 SECTOR 0B0A R | 6 SECTOR_B 0FE2 R | 6 SECTOR_I 0B1C R - 6 SECTRN 01E9 R | 6 SELDSK 01C4 R | 6 SENDINT 0A12 R - 6 SETDMA 01EC R | 6 SETSEC 01E3 R | 6 SETTRACK 0924 R - 6 SETTRK 01DD R | 6 SETUPDRI 07BF R | 6 SHEAD 0AFA R - 6 SNBIT 0AFC R | 6 SPT_0 00A3 R | 6 SPT_1 00B2 R - 6 SPT_2 00C1 R | 6 SPT_3 00D0 R | 6 SPT_4 00DF R - 6 SPT_5 00EE R | 6 SPT_6 00FD R | 6 SPT_7 010C R - 6 SREC 0AFB R | 6 SRTHUT 0AF2 R | 6 ST0 0AF6 R - 6 ST0A 0AFD R | 6 ST1 0AF7 R | 6 ST1A 0AFE R - 6 ST2 0AF8 R | TERMCN = 0001 | 6 TRACK 0B02 R - 6 TRFLSEC 0282 R | TRUE = 0001 | 6 TXT_RO_E 0A8C R - 6 TXT_STAR 0AAD R | UART = 0068 | 6 UNIT 0AEA R - VDU_INIT= 0100 | 6 WAINT 095A R | 6 WBOOT 0146 R - 6 WBOOTE 0003 R | 6 WRITE 03D7 R | 6 WRITE_AT 048E R - 6 WRITE_AT 04B4 R | 6 WRITE_DI 0A74 R | 6 WRITE_FL 0425 R - 6 WRITE_FL 045E R | 6 WRITE_FL 0444 R | 6 WRITE_HD 04BB R - 6 WRITE_ID 0466 R | 6 WRITE_ID 0487 R | 6 WRITE_RA 03FD R - 6 WRITE_RE 043C R | 6 _cbios 0000 GR | 6 _cbios_e 11EB GR - 6 _cbios_s 0000 GR - ASxxxx Assembler V02.00 + NoICE + SDCC mods + Flat24 (Zilog Z80 / Hitachi HD64180), page 2. -cbios.s derived from cbios.asm -Area Table - - 0 _CODE size 0 flags 0 - 1 _DATA size 0 flags 0 - 2 _OVERLAY size 0 flags 0 - 3 _HOME size 0 flags 0 - 4 _GSINIT size 0 flags 0 - 5 _GSFINAL size 0 flags 0 - 6 _CBIOS size 11EB flags 0 - 7 _CABS size 0 flags 0 diff --git a/doug/src/cbiosn8.arf b/doug/src/cbiosn8.arf deleted file mode 100755 index a32ae1a9..00000000 --- a/doug/src/cbiosn8.arf +++ /dev/null @@ -1,6 +0,0 @@ --mjx --i cbioshc.ihx --k /usr/local/share/sdcc/lib/z80 --l z80 -cbioshc.rel --e diff --git a/doug/src/cbiosn8.lst b/doug/src/cbiosn8.lst deleted file mode 100755 index ea08c586..00000000 --- a/doug/src/cbiosn8.lst +++ /dev/null @@ -1,1718 +0,0 @@ - 1 ;-------------------------------------------------------- - 2 ; cbioshc.s derived from CPM22-HC.ASM by dwg 5/18-30/2011 - 3 ;-------------------------------------------------------- - 4 .module cbioshc - 5 .optsdcc -mz80 - 6 ;-------------------------------------------------------- - 7 ; Public variables in this module - 8 ;-------------------------------------------------------- - 9 .globl _cbioshc - 10 ;-------------------------------------------------------- - 11 ; special function registers - 12 ;-------------------------------------------------------- - 13 ;-------------------------------------------------------- - 14 ; ram data - 15 ;-------------------------------------------------------- - 16 .area _DATA - 17 ;-------------------------------------------------------- - 18 ; overlayable items in ram - 19 ;-------------------------------------------------------- - 20 .area _OVERLAY - 21 ;-------------------------------------------------------- - 22 ; external initialized ram data - 23 ;-------------------------------------------------------- - 24 ;-------------------------------------------------------- - 25 ; global & static initialisations - 26 ;-------------------------------------------------------- - 27 .area _HOME - 28 .area _GSINIT - 29 .area _GSFINAL - 30 .area _GSINIT - 31 ;-------------------------------------------------------- - 32 ; Home - 33 ;-------------------------------------------------------- - 34 .area _HOME - 35 .area _HOME - 36 ;-------------------------------------------------------- - 37 ; code - 38 ;-------------------------------------------------------- - 39 .area _CBIOS - 0000 40 _cbioshc_start:: - 0000 41 _cbioshc: - 42 - 43 ;************************************************************** - 44 ;* - 45 ;* C B I O S f o r - 46 ;* - 47 ;* T e s t P r o t o t y p e - 48 ;* - 49 ;* by Andrew Lynch, with input from many sources - 50 ;* Updated 24-Mar-2009 Max Scane - changed seldsk: to not save bogus drive value - 51 ;* changed a: to be ram drive, B: to be rom disk - 52 ;* Updated 1-Jun-2010 Max Scane - Changed DPBs to be more sane - 53 ;* Updated 1-Jul-2010 Max Scane - Added PPIDE driver and conditionals - 54 ;* Updated April 2011 Max Scane - Adapted for the N8VEM Home Computer - 55 ;************************************************************** - 56 ; - 57 ; SKELETAL CBIOS FOR FIRST LEVEL OF CP/M 2.0 ALTERATION - 58 ; WITH MODS FOR CP/M ROMDISK AND RAMDISK. - 59 ; - 60 ; ENTIRELY IN 8080 MNEUMONICS (SO ASM CAN BE USED) - 61 ; BUT ASSUMES A Z80! (remove) - 62 ; - 63 - 003C 64 MEM = 60 ; DOUGTEMP DOUGTEMP - 65 - 66 - 67 ;MSIZE .EQU 20 ;CP/M VERSION MEMORY SIZE IN KILOBYTES - 68 ;MSIZE .EQU 62 ;CP/M VERSION MEMORY SIZE IN KILOBYTES - 69 ; MEM defined in CPM22 above, line 0015 - 70 - 003C 71 MSIZE = MEM ;CP/M VERSION MEMORY SIZE IN KILOBYTES - 72 - 73 ; - 74 ; "BIAS" IS ADDRESS OFFSET FROM 3400H FOR MEMORY SYSTEMS - 75 ; THAN 16K (REFERRED TO AS "B" THROUGHOUT THE TEXT). - 76 ; - 77 - A000 78 BIAS = (MSIZE-20)*1024 - 79 - D400 80 CCP = 0x3400+BIAS ; base of ccp - 81 - DC06 82 BDOS = CCP+0x0806 ; base of BDOS - 83 - EA00 84 BIOS = CCP+0x1600 ; base of BIOS - 85 - 0004 86 CDISK = 0x0004 ; current disk number 0=a,...,15=p - 87 - 88 ; IOBYTE already defined in CPM22 above, line 0017 - 89 ;IOBYTE .EQU 0003H ;INTEL I/O BYTE - 90 - 91 ; since the assembly has been broken into pieces, - 92 ; this symbols wasn't previously encountered. - 93 ; It could be exported from other module, but why? - 0003 94 IOBYTE = 0x0003 - 95 - 96 ; - 97 ; CONSTANTS - 98 - 99 - 00FF 100 END = 0x0FF - 101 - 102 - 000D 103 CR = 0x0d - 000A 104 LF = 0x0a - 105 - 0094 106 DEFIOB = 0x94 ; default IOBYTE (TTY,RDR,PUN,LPT) - 107 - 108 ; - 109 - 0100 110 ROMSTART_MON = 0x0100 ; where the monitor is stored in ROM - 111 - F800 112 RAMTARG_MON = 0x0f800 ; where the monitor starts in RAM - 113 - 0800 114 MOVSIZ_MON = 0x0800 ; monitor is 2K in length - 115 - 0900 116 ROMSTART_CPM = 0x0900 ; where ccp+bdos+bios is stored in ROM - 117 - D400 118 RAMTARG_CPM = 0x0D400 ; where ccp+bdos+bios starts in RAM - 119 - 120 ;dwg; INTERESTING - 0x15FF is 4K+1K+512-1, not 5KB - 121 ;dwg;MOVSIZ_CPM: .EQU $15FF ; CCP, BDOS IS 5KB IN LENGTH - 15FF 122 MOVSIZ_CPM = 0x15FF ; ccp+bdos is 5KB in length - 123 - 0080 124 HC_REG_BASE = 0x80 ; N8 I/I Regs $80-9F - 125 - 0080 126 PPI1 = HC_REG_BASE+0x00 - 127 - 0094 128 ACR = HC_REG_BASE+0x14 - 129 - 0096 130 RMAP = ACR+2 - 131 - 0040 132 IO_REG_BASE = 0x40 ; IO reg base offset for Z1x80 - 133 - 0040 134 CNTLA0 = IO_REG_BASE+0x00 - 135 - 0042 136 CNTLB0 = IO_REG_BASE+0x02 - 137 - 0044 138 STAT0 = IO_REG_BASE+0x04 - 139 - 0046 140 TDR0 = IO_REG_BASE+0x06 - 141 - 0048 142 RDR0 = IO_REG_BASE+0x08 - 143 - 0052 144 ASEXT0 = IO_REG_BASE+0x12 - 145 - 0078 146 CBR = IO_REG_BASE+0x38 - 147 - 0079 148 BBR = IO_REG_BASE+0x39 - 149 - 007A 150 CBAR = IO_REG_BASE+0x3A - 151 - 152 ; - 153 ; - 154 ; PIO 82C55 I/O IS ATTACHED TO THE FIRST IO BASE ADDRESS - 155 - 0080 156 IDELSB = PPI1+0 ; LSB - 157 - 0081 158 IDEMSB = PPI1+1 ; MSB - 159 - 0082 160 IDECTL = PPI1+2 ; Control Signals - 161 - 0083 162 PIO1CONT = PPI1+3 ; Control Byte PIO 82C55 - 163 - 164 ; PPI control bytes for read and write to IDE drive - 165 - 0092 166 rd_ide_8255 = 0b10010010 ; ide_8255_ctl out ide_8255_lsb/msb input - 167 - 0080 168 wr_ide_8255 = 0b10000000 ; all three ports output - 169 - 170 ;ide control lines for use with ide_8255_ctl. Change these 8 - 171 ;constants to reflect where each signal of the 8255 each of the - 172 ;ide control signals is connected. All the control signals must - 173 ;be on the same port, but these 8 lines let you connect them to - 174 ;whichever pins on that port. - 175 - 0001 176 ide_a0_line = 0x01 ; direct from 8255 to ide interface - 177 - 0002 178 ide_a1_line = 0x02 ; direct from 8255 to ide intereface - 179 - 0004 180 ide_a2_line = 0x04 ; direct from 8255 to ide interface - 181 - 0008 182 ide_cs0_line = 0x08 ; inverter between 8255 and ide interface - 183 - 0010 184 ide_cs1_line = 0x10 ; inverter between 8255 and ide interface - 185 - 0020 186 ide_wr_line = 0x20 ; inverter between 8255 and ide interface - 187 - 0040 188 ide_rd_line = 0x40 ; inverter between 8255 and ide interface - 189 - 0080 190 ide_rst_line = 0x80 ; inverter between 8255 and ide interface - 191 - 192 ;------------------------------------------------------------------ - 193 ; More symbolic constants... these should not be changed, unless of - 194 ; course the IDE drive interface changes, perhaps when drives get - 195 ; to 128G and the PC industry will do yet another kludge. - 196 - 197 ;some symbolic constants for the ide registers, which makes the - 198 ;code more readable than always specifying the address pins - 199 - 0008 200 ide_data = ide_cs0_line - 0009 201 ide_err = ide_cs0_line + ide_a0_line - 000A 202 ide_sec_cnt = ide_cs0_line + ide_a1_line - 000B 203 ide_sector = ide_cs0_line + ide_a1_line + ide_a0_line - 000C 204 ide_cyl_lsb = ide_cs0_line + ide_a2_line - 000D 205 ide_cyl_msb = ide_cs0_line + ide_a2_line + ide_a0_line - 000E 206 ide_head = ide_cs0_line + ide_a2_line + ide_a1_line - 000F 207 ide_command = ide_cs0_line + ide_a2_line + ide_a1_line + ide_a0_line - 000F 208 ide_status = ide_cs0_line + ide_a2_line + ide_a1_line + ide_a0_line - 0016 209 ide_control = ide_cs1_line + ide_a2_line + ide_a1_line - 0017 210 ide_astatus = ide_cs1_line + ide_a2_line + ide_a1_line + ide_a0_line - 211 - 212 ;IDE Command Constants. These should never change. - 213 - 0010 214 ide_cmd_recal = 0x10 - 0020 215 ide_cmd_read = 0x20 - 0030 216 ide_cmd_write = 0x30 - 0091 217 ide_cmd_init = 0x91 - 00EC 218 ide_cmd_id = 0x0ec - 00E0 219 ide_cmd_spindown = 0xe0 - 00E1 220 ide_cmd_spinup = 0xe1 - 221 - 222 - 223 ; .ORG BIOS ;ORIGIN OF THIS PROGRAM - 224 - 225 - 226 ;dwg;NSECTS .EQU ($-CCP)/128 ;WARM START SECTOR COUNT - 227 - 228 ; - 229 ; JUMP VECTOR FOR INDIVIDUAL SUBROUTINES - 230 - 0000 C3rDDs00 231 JP BOOT ;COLD START - 0003 C3rF5s00 232 WBOOTE: JP WBOOT ;WARM START - 0006 C3r2Fs01 233 JP CONST ;CONSOLE STATUS - 0009 C3r41s01 234 JP CONIN ;CONSOLE CHARACTER IN - 000C C3r53s01 235 JP CONOUT ;CONSOLE CHARACTER OUT - 000F C3r65s01 236 JP LIST ;LIST CHARACTER OUT (NULL ROUTINE) - 0012 C3r6Bs01 237 JP PUNCH ;PUNCH CHARACTER OUT (NULL ROUTINE) - 0015 C3r6Es01 238 JP READER ;READER CHARACTER OUT (NULL ROUTINE) - 0018 C3rC6s01 239 JP HOME ;MOVE HEAD TO HOME POSITION - 001B C3rAFs01 240 JP SELDSK ;SELECT DISK - 001E C3rC9s01 241 JP SETTRK ;SET TRACK NUMBER - 0021 C3rCFs01 242 JP SETSEC ;SET SECTOR NUMBER - 0024 C3rD8s01 243 JP SETDMA ;SET DMA ADDRESS - 0027 C3rDEs01 244 JP READ ;READ DISK - 002A C3r02s02 245 JP WRITE ;WRITE DISK - 002D C3r68s01 246 JP LISTST ;RETURN LIST STATUS (NULL ROUTINE) - 0030 C3rD5s01 247 JP SECTRN ;SECTOR TRANSLATE - 248 - 249 ; - 250 ; FIXED DATA TABLES FOR ALL DRIVES - 251 ; 0= RAMDISK, 1=ROMDISK, 2=HDPART1, 3=HDPART2 - 252 ; DISK PARAMETER HEADER FOR DISK 00 (RAM Disk) - 0033 253 DPBASE: - 0033 00 00 00 00 254 .DW 0x0000,0x0000 - 0037 00 00 00 00 255 .DW 0x0000,0x0000 - 003Br7Cs07r83s00 256 .DW DIRBF,DPBLK0 - 003Fr9Es0ArFCs07 257 .DW CHK00,ALL00 - 258 - 259 ; DISK PARAMETER HEADER FOR DISK 05 (Large ROM Disk) - 0043 00 00 00 00 260 .DW 0x0000,0x0000 - 0047 00 00 00 00 261 .DW 0x0000,0x0000 - 004Br7Cs07rCEs00 262 .DW DIRBF,DPBLK5 - 004Fr9Es0Ar5Es0A 263 .DW CHK05,ALL05 - 264 - 265 - 266 ; DISK PARAMETER HEADER FOR DISK 02 (8MB disk Partition) - 0053 00 00 00 00 267 .DW 0x0000,0x0000 - 0057 00 00 00 00 268 .DW 0x0000,0x0000 - 005Br7Cs07rA1s00 269 .DW DIRBF,DPBLK2 - 005Fr9Es0Ar20s08 270 .DW CHK02,ALL02 - 271 - 272 ; DISK PARAMETER HEADER FOR DISK 03 (8MB disk Partition) - 0063 00 00 00 00 273 .DW 0x0000,0x0000 - 0067 00 00 00 00 274 .DW 0x0000,0x0000 - 006Br7Cs07rB0s00 275 .DW DIRBF,DPBLK3 - 006Fr9Es0Ar1Fs09 276 .DW CHK03,ALL03 - 277 - 278 ; DISK PARAMETER HEADER FOR DISK 04 (??? third disk partition ???) - 0073 00 00 00 00 279 .DW 0x0000,0x0000 - 0077 00 00 00 00 280 .DW 0x0000,0x0000 - 007Br7Cs07rBFs00 281 .DW DIRBF,DPBLK4 - 007Fr9Es0Ar1Es0A 282 .DW CHK04,ALL04 - 283 - 0083 284 DPBLK0: ;DISK PARAMETER BLOCK (RAMDISK 512K, 448K usable) - 0083 00 01 285 SPT_1: .DW 256 ; 256 SECTORS OF 128 BYTES PER 32K TRACK - 0085 04 286 BSH_1: .DB 4 ; BLOCK SHIFT FACTOR (SIZE OF ALLOCATION BLOCK) - 0086 0F 287 BLM_1: .DB 15 ; PART OF THE ALLOCATION BLOCK SIZE MATH - 0087 01 288 EXM_1: .DB 1 ; DEFINES SIZE OF EXTENT (DIRECTORY INFO) - 0088 DF 00 289 DSM_1: .DW 223 ; BLOCKSIZE [2048] * NUMBER OF BLOCKS + 1 = DRIVE SIZE - 008A FF 00 290 DRM_1: .DW 255 ; NUMBER OF DIRECTORY ENTRIES - 008C F0 291 AL0_1: .DB 0b11110000 ; BIT MAP OF SPACE ALLOCATED TO DIRECTORY - 008D 00 292 AL1_1: .DB 0b00000000 ; DIRECTORY CAN HAVE UP TO 16 BLOCKS ALLOCATED - 008E 00 00 293 CKS_1: .DW 0 ; SIZE OF DIRECTORY CHECK [0 IF NON REMOVEABLE] - 0090 02 00 294 OFF_1: .DW 2 ; 2 TRACK RESERVED [FIRST 64K OF RAM] - 295 ; Note: changed to 2 tracks to skip over the 1st 64KB or RAM. - 296 - 0092 297 DPBLK1: ;DISK PARAMETER BLOCK (ROMDISK 32KB WITH 16 2K TRACKS, 22K usable) - 0092 10 00 298 SPT_0: .DW 16 ; 16 SECTORS OF 128 BYTES PER 2K TRACK - 0094 03 299 BSH_0: .DB 3 ; BLOCK SHIFT FACTOR (SIZE OF ALLOCATION BLOCK) - 0095 07 300 BLM_0: .DB 7 ; PART OF THE ALLOCATION BLOCK SIZE MATH - 0096 00 301 EXM_0: .DB 0 ; DEFINES SIZE OF EXTENT (DIRECTORY INFO) - 0097 1F 00 302 DSM_0: .DW 31 ; BLOCKSIZE [1024] * NUMBER OF BLOCKS + 1 = DRIVE SIZE - 0099 1F 00 303 DRM_0: .DW 31 ; NUMBER OF DIRECTORY ENTRIES - 009B 80 304 AL0_0: .DB 0b10000000 ; BIT MAP OF SPACE ALLOCATED TO DIRECTORY - 009C 00 305 AL1_0: .DB 0b00000000 ; DIRECTORY CAN HAVE UP TO 16 BLOCKS ALLOCATED - 009D 00 00 306 CKS_0: .DW 0 ; SIZE OF DIRECTORY CHECK [0 IF NON REMOVEABLE] - 009F 05 00 307 OFF_0: .DW 5 ; FIRST 5 TRACKS TRACKS RESERVED (10K FOR SYSTEM) - 308 ; SYSTEM IS ROM LOADER, CCP, BDOS, CBIOS, AND MONITOR - 309 ; - 310 ; IMPORTANT NOTE: TRACKS $00 - $04 OF 2K BYTES - 311 ; EACH ARE MARKED WITH THE OFF_0 SET TO 5 AS - 312 ; SYSTEM TRACKS. USABLE ROM DRIVE SPACE - 313 ; STARTING AFTER THE FIFTH TRACK (IE, TRACK $05) - 314 ; MOST LIKELY FIX TO THIS IS PLACING A DUMMY - 315 ; FIRST 10K ROM CONTAINS THE ROM LOADER, MONITOR, - 316 ; CCP, BDOS, BIOS, ETC (5 TRACKS * 2K EACH) - 317 - 318 - 00A1 319 DPBLK2: ;DISK PARAMETER BLOCK (IDE HARD DISK 8MB) - 00A1 00 01 320 SPT_2: .DW 256 ; 256 SECTORS OF 128 BYTES PER 32K TRACK - 00A3 05 321 BSH_2: .DB 5 ; BLOCK SHIFT FACTOR (SIZE OF ALLOCATION BLOCK) - 00A4 1F 322 BLM_2: .DB 31 ; PART OF THE ALLOCATION BLOCK SIZE MATH - 00A5 01 323 EXM_2: .DB 1 ; DEFINES SIZE OF EXTENT (DIRECTORY INFO) - 00A6 F7 07 324 DSM_2: .DW 2039 ; BLOCKSIZE [4096] * NUMBER OF BLOCKS + 1 = DRIVE SIZE - 325 ; HD PARTITION 2 IS 16128 SECTORS LONG - 326 ; AT 512 BYTES EACH WHICH IS - 327 ; 2016 BLOCKS AT 4096 BYTES A PIECE. - 00A8 FF 01 328 DRM_2: .DW 511 ; NUMBER OF DIRECTORY ENTRIES - 00AA F0 329 AL0_2: .DB 0b11110000 ; BIT MAP OF SPACE ALLOCATED TO DIRECTORY - 00AB 00 330 AL1_2: .DB 0b00000000 ; DIRECTORY CAN HAVE UP TO 16 BLOCKS ALLOCATED - 00AC 00 00 331 CKS_2: .DW 0 ; SIZE OF DIRECTORY CHECK [0 IF NON REMOVEABLE] - 00AE 01 00 332 OFF_2: .DW 1 ; 1 TRACK (32K) RESERVED FOR SYSTEM - 333 - 00B0 334 DPBLK3: ;DISK PARAMETER BLOCK (IDE HARD DISK 8MB) - 00B0 00 01 335 SPT_3: .DW 256 ; 256 SECTORS OF 128 BYTES PER 32K TRACK - 00B2 05 336 BSH_3: .DB 5 ; BLOCK SHIFT FACTOR (SIZE OF ALLOCATION BLOCK) - 00B3 1F 337 BLM_3: .DB 31 ; PART OF THE ALLOCATION BLOCK SIZE MATH - 00B4 01 338 EXM_3: .DB 1 ; DEFINES SIZE OF EXTENT (DIRECTORY INFO) - 00B5 F7 07 339 DSM_3: .DW 2039 ; BLOCKSIZE [4096] * NUMBER OF BLKS + 1 = DRIVE SIZE - 340 ; HD PARTITION 3 IS 16128 SECTORS LONG - 341 ; AT 512 BYTES EACH WHICH IS - 342 ; 2016 BLOCKS AT 4096 BYTES A PIECE. - 00B7 FF 01 343 DRM_3: .DW 511 ; NUMBER OF DIRECTORY ENTRIES - 00B9 F0 344 AL0_3: .DB 0b11110000 ; BIT MAP OF SPACE ALLOCATED TO DIRECTORY - 00BA 00 345 AL1_3: .DB 0b00000000 ; DIRECTORY CAN HAVE UP TO 16 BLOCKS ALLOCATED - 00BB 00 00 346 CKS_3: .DW 0 ; SIZE OF DIRECTORY CHECK [0 IF NON REMOVEABLE] - 00BD 01 00 347 OFF_3: .DW 1 ; 1 TRACK (32K) RESERVED FOR SYSTEM - 348 - 00BF 349 DPBLK4: ;DISK PARAMETER BLOCK (IDE HARD DISK 1024K) - 00BF 00 01 350 SPT_4: .DW 256 ; 256 SECTORS OF 128 BYTES PER 32K TRACK - 00C1 04 351 BSH_4: .DB 4 ; BLOCK SHIFT FACTOR (SIZE OF ALLOCATION BLOCK) - 00C2 0F 352 BLM_4: .DB 15 ; PART OF THE ALLOCATION BLOCK SIZE MATH - 00C3 00 353 EXM_4: .DB 0 ; DEFINES SIZE OF EXTENT (DIRECTORY INFO) - 00C4 F1 01 354 DSM_4: .DW 497 ; BLKSIZE [2048] * NUMBER OF BLKS + 1 = DRIVE SIZE - 355 ; HD PARTITION 4 IS 4032 SECTORS LONG - 356 ; AT 512 BYTES EACH WHICH IS - 357 ; 1008 BLOCKS AT 2048 BYTES A PIECE. - 358 ; NOT USING ALL OF THE AVAILABLE SECTORS SINCE THIS - 359 ; DRIVE IS INTENDED TO EMULATE A ROM DRIVE AND COPIED - 360 ; INTO A ROM IN THE FUTURE. - 00C6 FF 00 361 DRM_4: .DW 255 ; NUMBER OF DIRECTORY ENTRIES - 00C8 F0 362 AL0_4: .DB 0b11110000 ; BIT MAP OF SPACE ALLOCATED TO DIRECTORY - 00C9 00 363 AL1_4: .DB 0b00000000 ; DIRECTORY CAN HAVE UP TO 16 BLOCKS ALLOCATED - 00CA 00 00 364 CKS_4: .DW 0 ; SIZE OF DIRECTORY CHECK [0 IF NON REMOVEABLE] - 00CC 01 00 365 OFF_4: .DW 1 ; 1 TRACK RESERVED [FIRST 32K OF PARTITION] - 366 - 367 ; - 00CE 368 DPBLK5: ;DISK PARAMETER BLOCK (ROMDISK 1MB) - 00CE 00 01 369 SPT_5: .DW 256 ; 256 SECTORS OF 128 BYTES PER 32K TRACK - 00D0 04 370 BSH_5: .DB 4 ; BLOCK SHIFT FACTOR (SIZE OF ALLOCATION BLOCK) - 00D1 0F 371 BLM_5: .DB 15 ; PART OF THE ALLOCATION BLOCK SIZE MATH - 00D2 00 372 EXM_5: .DB 0 ; DEFINES SIZE OF EXTENT (DIRECTORY INFO) - 00D3 EF 01 373 DSM_5: .DW 495 ; BLKSIZE [2048] * NUMBER OF BLKS +1 =DRIVE SIZE - 374 ;DSM_5: .DW 511 ; BLKSIZE [2048] * NUMBER OF BLKS +1 =DRIVE SIZE - 00D5 FF 00 375 DRM_5: .DW 255 ; NUMBER OF DIRECTORY ENTRIES - 00D7 F0 376 AL0_5: .DB 0b11110000 ; BIT MAP OF SPACE ALLOCATED TO DIRECTORY - 00D8 00 377 AL1_5: .DB 0b00000000 ; DIR CAN HAVE UP TO 16 BLOCKS ALLOCATED - 00D9 00 00 378 CKS_5: .DW 0 ; SIZE OF DIR CHECK [0 IF NON REMOVEABLE] - 00DB 01 00 379 OFF_5: .DW 1 ; 1 TRACK RESERVED [FIRST 32K OF ROM] - 380 - 381 ; - 382 ; END OF FIXED TABLES - 383 ; - 384 ; INDIVIDUAL SUBROUTINES TO PERFORM EACH FUNCTION - 385 - 00DD 386 BOOT: ;SIMPLEST CASE IS TO JUST PERFORM PARAMETER INITIALIZATION - 00DD F3 387 di ; disable interrupts - 388 ; IM 1 ; SET INTERRUPT MODE 1 - 389 ; .DB $ED,$56 ; Z80 "IM 1" INSTRUCTION - 390 - 00DE 3E 80 391 ld a,#0x80 - 392 - 393 ; out0 ACR - 394 ; .BYTE $ED,$39,ACR ; ensure that the ROM is switched out - 395 - 00E0 D3 94 396 out (ACR),a - 397 - 00E2 3E 01 398 ld a,#1 - 00E4 32 04 00 399 ld (CDISK),a ; select disk 0 - 400 - 00E7 3E 94 401 ld a,#DEFIOB - 00E9 32 03 00 402 ld (IOBYTE),a - 403 - 404 ; ei ; enable interrupts - 405 - 00EC 21r30s05 406 ld hl,#TXT_STARTUP_MSG - 00EF CDr89s03 407 CALL PRTMSG - 408 - 00F2 C3r0Es01 409 JP GOCPM ;INITIALIZE AND GO TO CP/M - 410 - 411 ; - 00F5 412 WBOOT: ;SIMPLEST CASE IS TO READ THE DISK UNTIL ALL SECTORS LOADED - 413 ; WITH A ROMDISK WE SELECT THE ROM AND THE CORRECT PAGE [0] - 414 ; THEN COPY THE CP/M IMAGE (CCP, BDOS, BIOS, MONITOR) TO HIGH RAM - 415 ; LOAD ADDRESS. - 416 - 00F5 F3 417 DI ; DISABLE INTERRUPT - 418 - 00F6 31 80 00 419 ld SP,#0x0080 ; use space below buffer for stack - 420 - 421 ; IM 1 ; SET INTERRUPT MODE 1 - 422 ; .DB $ED,$56 ; Z80 "IM 1" INSTRUCTION - 423 - 00F9 AF 424 xor a,a - 425 - 426 ; CHEAP ZERO IN ACC - 427 ; mvi a,00h ; switch in the ROM - 428 ; out0 ACR - 429 ; .BYTE $ED,$39,ACR - 430 - 00FA D3 94 431 out (ACR),a - 432 - 00FC AF 433 xor a,a - 434 - 435 ; out0 RMAP - 436 ; .BYTE $ED,$39,$F6 - 437 - 00FD D3 96 438 out (RMAP),a ; set the rom map - 439 - 440 ; Just reload CCP and BDOS - 441 - 00FF 21 00 09 442 ld hl,#ROMSTART_CPM ; where in rom cp/m is stored (1st byte) - 0102 11 00 D4 443 ld de,#RAMTARG_CPM ; where in ram to move ccp+BDOS to - 0105 01 FF 15 444 ld bc,#MOVSIZ_CPM - 0108 ED B0 445 ldir - 446 - 010A 3E 80 447 ld a,#0x80 - 010C D3 94 448 out (ACR),a - 449 - 450 ; EI ; ENABLE INTERRUPTS - 451 - 452 ; - 453 ; END OF LOAD OPERATION, SET PARAMETERS AND GO TO CP/M - 010E 454 GOCPM: - 455 ;CPU RESET HANDLER - 010E 3E C3 456 ld a,#0xC3 ; C32 is a jump opcode - 0110 32 00 00 457 ld (0x0000),a - 0113 21r03s00 458 ld hl,#WBOOTE ; address of warm boot - 0116 22 01 00 459 ld (0x0001),hl ; set addr field for jmp at 0 - 460 - 0119 32 05 00 461 ld (0x0005),a ; for jump to bdos - 011C 21 06 DC 462 ld hl,#BDOS - 011F 22 06 00 463 ld (0x0006),hl - 464 - 0122 01 80 00 465 ld bc,#0x0080 ; default DMA address - 0125 CDrD8s01 466 CALL SETDMA - 467 - 0128 3A 04 00 468 ld a,(CDISK) ; get current disk number - 012B 4F 469 ld c,a ; send to the ccp - 012C C3 00 D4 470 JP CCP ;GO TO CP/M FOR FURTHER PROCESSING - 471 - 472 - 473 ; - 474 ;---------------------------------------------------------------------------------------------------------------------- - 475 ; N8VEM Home computer I/O handlers - 476 ; - 477 ; This implementation uses IOBYTE and allocates devices as follows: - 478 ; - 479 ; TTY - Driver for the Z180 ASCI port 0 - 480 ; CRT - Driver for the - 481 ; UC1 - Driver for the - 482 ; xxx - Driver for the - 483 ; - 484 ; Logical device drivers - these pass control to the physical - 485 ; device drivers depending on the value of the IOBYTE - 486 ; - 487 - 012F 488 CONST: ;CONSOLE STATUS, RETURN 0FFH IF CHARACTER READY, 00H IF NOT - 489 - 012F 3A 03 00 490 ld a,(IOBYTE) - 0132 E6 03 491 and a,#3 - 0134 FE 00 492 cp #0 - 0136 CAr91s01 493 jp z,TTYISTS - 494 - 0139 FE 01 495 cp #1 - 013B CArA9s01 496 jp z,CRTISTS - 497 - 013E C3r76s01 498 jp NULLSTS - 499 - 500 - 501 - 502 - 0141 503 CONIN: ;CONSOLE CHARACTER INTO REGISTER A - 0141 3A 03 00 504 ld a,(IOBYTE) - 0144 E6 03 505 and a,#3 - 0146 FE 00 506 cp #0 - 0148 CAr79s01 507 jp z,TTYIN - 014B FE 01 508 cp #1 - 014D CArA3s01 509 jp z,CRTIN - 0150 C3r71s01 510 jp NULLIN - 511 - 512 - 0153 513 CONOUT: ;CONSOLE CHARACTER OUTPUT FROM REGISTER C - 0153 3A 03 00 514 ld a,(IOBYTE) - 0156 E6 03 515 and a,#3 ; isolate console bits - 0158 FE 00 516 cp #0 - 015A CAr85s01 517 jp z,TTYOUT - 015D FE 01 518 cp #1 - 015F CArA6s01 519 jp z,CRTOUT - 0162 C3r74s01 520 jp NULLOUT - 521 - 0165 522 LIST: ;LIST CHARACTER FROM REGISTER C - 0165 C3r74s01 523 jp NULLOUT - 524 - 525 - 526 - 0168 527 LISTST: ;RETURN LIST STATUS (0 IF NOT READY, 1 IF READY) - 0168 C3r76s01 528 jp NULLSTS - 529 - 530 ; - 016B 531 PUNCH: ;PUNCH CHARACTER FROM REGISTER C - 016B C3r74s01 532 jp NULLOUT - 533 - 534 ; - 016E 535 READER: ;READ CHARACTER INTO REGISTER A FROM READER DEVICE - 536 - 016E C3r71s01 537 jp NULLIN ; currently not used - 538 - 539 - 540 - 541 ;---------------------------------------------------------------------------------------------------------------------------------------- - 542 ; - 543 ; Here are the physical io device drivers - 544 ; - 545 ; Null driver - this is a dummy driver for the NULL device - 546 - 0171 547 NULLIN: - 0171 3E 1A 548 ld a,#0x1a - 0173 C9 549 ret - 550 - 0174 551 NULLOUT: - 0174 79 552 ld a,c - 0175 C9 553 ret - 554 - 0176 555 NULLSTS: - 0176 3E 01 556 ld a,#1 - 0178 C9 557 ret - 558 - 559 ; - 560 ;--------------------------------------------------------------------------------------------------------------------------------------------- - 561 ; - 562 ; TTY Driver (programmed i/o) this is the driver for the Home Computer console port - 563 ; - 0179 564 TTYIN: - 0179 CDr91s01 565 CALL TTYISTS; IS A CHAR READY TO BE READ FROM UART? - 017C FE 00 566 cp #0 - 017E CAr79s01 567 jp z,TTYIN - 568 - 569 ; IN0 A,(RDR0) - 570 - 571 ;dwg; .BYTE $ED,$38,RDR0 - 0181 ED 38 48 572 .byte 0xED,0x38,RDR0 - 573 - 0184 C9 574 ret - 575 - 0185 576 TTYOUT: - 0185 CDr9As01 577 call TTYOSTS - 0188 A7 578 and a,a - 0189 CAr85s01 579 jp z,TTYOUT ; if not repeat - 580 - 018C 79 581 ld a,c ; get to accum - 582 - 583 ; OUT0 (TDR0),A - 018D ED 39 46 584 .byte 0xed,0x39,TDR0 - 585 - 0190 C9 586 ret - 587 - 0191 588 TTYISTS: - 589 ; IN0 A,(STAT0) - 590 ;dwg; .BYTE $ED,$38,STAT0 - 591 ;;dwg;; in0 a,(STAT0) - 0191 ED 38 44 592 .byte 0xed,0x38,STAT0 - 593 - 0194 E6 80 594 and a,#0x80 - 0196 C8 595 ret z ; is there a char ready? 0=no 1=yes - 0197 3E FF 596 ld a,#0xff - 0199 C9 597 ret ; NO, LEAVE $00 IN A AND RETURN - 598 - 019A 599 TTYOSTS: - 600 ; IN0 A,(STAT0) - 601 ;dwg; .BYTE $ED,$38,STAT0 - 602 ;;dwg;; in0 a,(STAT0) - 019A ED 38 44 603 .byte 0xed,0x38,STAT0 - 604 - 019D E6 02 605 and a,#2 - 019F C8 606 ret z - 01A0 3E FF 607 ld a,#0xff - 608 - 01A2 C9 609 ret ; NO, LEAVE $00 IN A AND RETURN - 610 ;--------------------------------------------------------------------------------------------------------------------------------------------- - 611 ; CRT Driver - This is the driver for the Prop VDU - 612 ; - 613 - 01A3 614 CRTIN: - 01A3 C3r71s01 615 jp NULLIN - 616 - 01A6 617 CRTOUT: - 01A6 C3r74s01 618 jp NULLOUT - 619 - 01A9 620 CRTISTS: - 01A9 C3r76s01 621 jp NULLSTS - 622 - 01AC 623 CRTOSTS: - 01AC C3r76s01 624 jp NULLSTS - 625 - 626 - 627 ;--------------------------------------------------------------------------------------------------------------------------------------------- - 628 ;; - 629 ; I/O DRIVERS FOR THE DISK FOLLOW - 630 ; FOR NOW, WE WILL SIMPLY STORE THE PARAMETERS AWAY FOR USE - 631 ; IN THE READ AND WRITE SUBROUTINES - 632 ; - 633 - 634 ; - 635 ; SELECT DISK GIVEN BY REGISTER C - 636 ; - 01AF 637 SELDSK: - 638 - 01AF 21 00 00 639 ld hl,#0 ; error return code - 640 - 01B2 79 641 ld a,c - 642 - 01B3 FE 04 643 cp a,#4 ; must be between 0 and 4 - 01B5 D0 644 ret nc ; no carry if 4,5,6,7 - 01B6 79 645 ld a,c - 01B7 32r68s05 646 ld (DISKNO),a ; save valid disk number - 647 - 648 ; - 649 ; DISK NUMBER IS IN THE PROPER RANGE - 650 ; COMPUTE PROPER DISK PARAMETER HEADER ADDRESS - 651 - 01BA 6F 652 ld l,a ; l = disk num 0,1,2,3,4 - 01BB 26 00 653 ld h,#0 ; high order - 01BD 29 654 add hl,hl ; * 2 - 01BE 29 655 add hl,hl ; * 4 - 01BF 29 656 add hl,hl ; * 8 - 01C0 29 657 add hl,hl ; * 16 (size of each header) - 01C1 11r33s00 658 ld de,#DPBASE - 01C4 19 659 add hl,de ; hl = .DPBASE(DISKNO*16) - 01C5 C9 660 RET - 661 ; - 01C6 662 HOME: ;MOVE TO THE TRACK 00 POSITION OF CURRENT DRIVE - 663 ; TRANSLATE THIS CALL INTO A SETTRK CALL WITH PARAMETER 00 - 664 - 01C6 01 00 00 665 ld bc,#0 ; select track zero - 666 - 667 ; CALL SETTRK - 668 ; RET ;WE WILL MOVE TO 00 ON FIRST READ/WRITE - 669 ; FALL THROUGH TO SETTRK TO STORE VALUE - 670 - 01C9 671 SETTRK: ;SET TRACK GIVEN BY REGISTER BC - 01C9 60 672 ld h,b - 01CA 69 673 ld l,c - 01CB 22r62s05 674 ld (TRACK),hl - 01CE C9 675 RET - 676 ; - 01CF 677 SETSEC: ;SET SECTOR GIVEN BY REGISTER BC - 01CF 60 678 ld h,b - 01D0 69 679 ld l,c - 01D1 22r64s05 680 ld (SECTOR),hl - 01D4 C9 681 RET - 682 ; - 683 ; TRANSLATE THE SECTOR GIVEN BY BC USING THE - 684 ; TRANSLATE TABLE GIVEN BY DE - 685 ; ONLY USED FOR FLOPPIES! FOR ROMDISK/RAMDISK IT'S 1:1 - 686 ; DO THE NEXT ROUTINE IS A NULL (RETURNS THE SAME) - 01D5 687 SECTRN: - 01D5 60 688 ld h,b - 01D6 69 689 ld l,c - 01D7 C9 690 RET - 691 ; - 692 - 01D8 693 SETDMA: ;SET DMA ADDRESS GIVEN BY REGISTERS B AND C - 01D8 69 694 ld l,c - 01D9 60 695 ld h,b - 01DA 22r66s05 696 ld (DMAAD),hl - 01DD C9 697 RET - 698 - 699 ; READ DISK - 700 ; USES DE,DL, BC, ACC FLAGS - 701 ; Z80 COULD USE BLOCK MOVE [LDIR] BUT WRITTEN IN 8080 - 01DE 702 READ: - 703 ; DI ; DISABLE INTERRUPTS - 704 - 01DE 3Ar68s05 705 ld a,(DISKNO) - 706 ; FIND OUT WHICH DRIVE IS BEING REQUESTED - 707 ; ARE WE READING RAM OR ROM? - 01E1 FE 00 708 cp #0 - 01E3 CAr2Fs02 709 jp z,READ_RAM_DISK - 710 - 01E6 FE 01 711 cp #1 - 01E8 CAr5Fs02 712 jp z,READ_ROM_DISK - 713 - 01EB FE 02 714 cp #2 - 01ED CArB6s02 715 jp z,READ_HDPART1 - 716 - 01F0 FE 03 717 cp #3 - 01F2 CArC5s02 718 jp z,READ_HDPART2 ; READ FROM 8 MB IDE HD, PARTITION 2 - 719 - 01F5 FE 04 720 cp #4 - 01F7 CArD4s02 721 jp z,READ_HDPART3 ; READ FROM 1 MB IDE HD, PARTITION 4 - 722 - 01FA FE 05 723 cp #5 - 01FC CArD4s02 724 jp z,READ_HDPART4 ; READ FROM 1 MB IDE HD, PARTITION 5 - 725 - 01FF 3E 01 726 ld a,#1 ; BDOS WILL ALSO PRINT ITS OWN ERROR MESSAGE - 0201 C9 727 ret - 728 - 729 - 730 ; - 731 ; WRITE DISK - 732 ; - 0202 733 WRITE: - 734 ; DI ; DISABLE INTERRUPTS - 735 - 0202 3Ar68s05 736 ld a,(DISKNO) ; get drive - 737 - 738 ; ORA A ; SET FLAGS - 739 - 0205 FE 00 740 cp #0 ; find out which drive is being requested - 741 - 0207 CAr86s02 742 jp z,WRITE_RAM_DISK ; write to 448K ram disk - 743 - 020A FE 01 744 cp #1 - 020C CAr26s02 745 jp z,RDONLY ; jump to read only routine - 746 - 747 ; READ ONLY, FROM 22K EEPROM DISK, ERROR ON WRITE - 020F FE 02 748 cp #2 - 0211 CAr1Cs03 749 jp z,WRITE_HDPART1 ; write to 8MB IDE HD, Part 2 - 750 - 0214 FE 03 751 cp #3 - 0216 CAr2Bs03 752 jp z,WRITE_HDPART2 ; write to 8MB IDE HD, Part 3 - 753 - 0219 FE 04 754 cp #4 - 021B CAr3As03 755 jp z,WRITE_HDPART3 ; write to 1MB IDE HD, Part 4 - 756 - 021E FE 05 757 cp #5 - 0220 CAr3As03 758 jp z,WRITE_HDPART4 ; write to 1MB IDE HD Part 5 - 759 - 760 - 761 ; IF NONE OF THE OTHER DISKS, IT MUST BE - 762 ; THE RAM DISK, SO FALL THROUGH - 763 - 0223 3E 01 764 ld a,#1 ; send bad sector error back - 765 ; BDOS WILL ALSO PRINT ITS OWN ERROR MESSAGE - 0225 C9 766 ret - 767 - 768 - 769 - 0226 770 RDONLY: - 771 ; - 772 ; HANDLE WRITE TO READ ONLY - 773 ; - 774 ; SENDS A MESSAGE TO TERMINAL THAT ROM DRIVE IS NOT WRITEABLE - 775 ; DOES A PAUSE THEN RETURNS TO CPM WITH ERROR FLAGGED. THIS IS - 776 ; DONE TO ALLOW A POSSIBLE GRACEFUL EXIT (SOME APPS MAY PUKE). - 777 ; - 778 - 779 ; CODE TBD, PRINT A HEY WRONG DISK AND PAUSE 5 SEC AND - 780 ; CONTINUE. - 781 - 0226 21r0Fs05 782 ld hl,#TXT_RO_ERROR ; set hp --> error msg - 0229 CDr89s03 783 CALL PRTMSG ; PRINT ERROR MESSAGE - 784 - 022C 3E 01 785 ld a,#1 ; send bad sector error back - 786 ; BDOS WILL ALSO PRINT ITS OWN ERROR MESSAGE - 787 ; ADD 5 SECOND PAUSE ROUTINE HERE - 022E C9 788 ret - 789 - 790 ; - 791 ;-------------------------------------------------------------------------------------------------------------- - 792 ; - 793 ; DISK DRIVERS... - 794 ; - 795 ; DRIVER NEED TO DO SEVERAL THINGS FOR ROM AND RAM DISKS. - 796 ; - INTERRUPTS ARE NOT ALLOWED DURING LOW RAM/ROM ACCESS (DISABLE!) - 797 ; -TRANSLATE TRACK AND SECTOR INTO A POINTER TO WHERE THE 128 BYTE - 798 ; SECTOR BEGINS IN THE RAM/ROM - 799 ; -TRANSLATE THE DRIVE INTO A RAM/ROM SELECT, COMBINE WITH TRACK ADDRESS - 800 ; AND SEND TO THE MAP PORT. - 801 ; -COPY 128 BYTE FROM OR TO THE ROM/RAMDISK AND MEM POINTED TO BY DMA - 802 ; ADDRESS PREVIOUSLY STORED. - 803 ; -RESTORE MAP PORT TO PRIOR CONDITION BEFOR READ/WRITE - 804 ; - 805 ; - FIRST TRICK IS THAT WE MADE SECTORS 256 AS 256*128=32768. SO WE COPY - 806 ; THE LOW SECTOR ADDRESS TO THE LOW BYTE OF THE HL REGISTER AND THEN - 807 ; MULTIPLY BY 128. THIS RESULTS IN THE STARTING ADDR IN THE RAM OR ROM - 808 ; (0000 -> 7F80H) 32K PAGE. - 809 ; - 810 ; - TRICK TWO IS THE TRACK ADDRESS EQUALS THE 32K PAGE ADDRESS AND IS A - 811 ; DIRECT SELECT THAT CAN BE COPIED TO THE MAP PORT D0 THROUGH D5. D7 - 812 ; SELECTS THE DRIVE (ROM OR RAM). - 813 ; THAT MEANS THE LOW BYTE OF TRACK CONTAINS THE D0-D5 VALUE AND - 814 ; DISKNO HAS THE DRIVE SELECTED. WE FIRST COPY DISKNO TO ACC - 815 ; AND RIGHTSHIFT IT TO PLACE THAT IN BIT7, WE THEN ADD LOW BYTE OF - 816 ; TRACK TO ACC AND THEN SEND THAT TO THE MAP PORT. - 817 ; - 818 ; NOTE 1: A WRITE TO ROM SHOULD BE FLAGGED AS AN ERROR. - 819 ; NOTE 2: RAM MUST START AS A "FORMATTED DISK" IF BATTERY BACKED UP - 820 ; IT'S A DO ONCE AT COLD COLD START. IF NOT BATTERY BACKED UP - 821 ; IT WILL HAVE TO BE DONE EVERY TIME THE SYSTEM IS POWERED. - 822 ; FORMATTING THE RAM IS SIMPLE AS CLEARING THE DIRECTORY AREA - 823 ; TO A VALUE OF E5H (THE FIRST 8K OF TRACK 1 OR THE RAMDISK). - 824 ; IT COULD BE DONE AS A SIMPLE UTILITY PROGRAM STORED IN ROMDISK - 825 ; OR ANYTIME COLBOOT IS CALLED(LESS DESIREABLE). - 826 ; - 827 ; -WE NOW CAN COPY TO/FROM AS CORRECT FOR THE DEVICE 128 BYTES (SECTOR) - 828 ; TO OR FROM THE DMA ADDRESS. ALMOST! SINCE ROM OR RAM IS BEING PAGED - 829 ; WE HAVE TO COPY ANYTHING DESTINED FOR BELOW 8000H TO TEMP BUFFER - 830 ; THEN HANDLE THE PAGING. - 831 ; - 832 ; - 833 ; - LAST STEP IS TO RESTORE THE MAP PORT TO POINT TO THE RAM (TRACK 0) - 834 ; SO THE CP/M MEMORY MAP IS ALL RAM AGAIN AND NOT POINTING INTO THE - 835 ; DATA AREAS OR THE "DISK". - 836 ; SINCE THE RAM 0TH PAGE IS NOMINALLY THE LOW 32K OF RAM IN THE i - 837 ; SYSTEM WE CAN SEND A SIMPLE MVI A,80H ; OUT MPCL_ROM; MVI A,00H ; - 838 ; OUT MPCL_RAM. - 839 ; - 840 ; - THE READ OR WRITE OPERATION IS DONE. - 841 ; - 842 ; - 843 ; - 844 ; - 845 ; - 846 ; - 847 - 848 ; ACCESS ALGORITHM (ONLY APPLICABLE TO 32K ROM PART!) - 022F 849 READ_RAM_DISK: - 022F F3 850 DI ; IF RAM, PROCEED WITH NORMAL TRACK/SECTOR READ - 0230 CDr98s03 851 CALL SECPAGE ; SETUP FOR READ OF RAM OR ROM DISK - 852 - 0233 2Ar62s05 853 ld hl,(TRACK) ; multiply by 8 (4k segs) - 854 - 855 ;dwg; dad h ; *2 - 0236 29 856 add hl,hl - 857 - 858 ;dwg; dad h ; *4 - 0237 29 859 add hl,hl - 860 - 861 ;dwg; dad h ; *8 - 0238 29 862 add hl,hl - 863 - 864 ;dwg; MOV A,L ; get track in L - 0239 7D 865 ld a,l - 866 - 867 ; out0 BBR ; select RAM bank - 868 - 869 ;dwg; .BYTE $ED,$39,BBR - 870 ;;dwg;; out0 BBR - 023A ED 39 79 871 .byte 0xed,0x39,BBR - 872 - 023D 21r7Cs05 873 ld hl,#TMPBUF ; load hl with temp buf addr - 0240 54 874 ld d,h ; get it into de - 0241 5D 875 ld e,l - 0242 2Ar6Ds05 876 ld hl,(SECST) ; rom/ram addr - 0245 01 80 00 877 ld bc,#128 - 0248 ED B0 878 ldir - 879 - 880 ; - 881 ; NOW WITH THE ROM/RAM DATA IN THE BUFFER WE CAN NOW MOVE IT TO THE - 882 ; DMA ADDRESS (IN RAM) - 883 ; - 884 - 024A 3E 00 885 ld a,#0 ; return to system bank - 886 - 887 ; out0 BBR ; select RAM bank - 888 - 889 ;dwg; .BYTE $ED,$39,BBR - 890 ;;dwg;; out0 BBR - 024C ED 39 79 891 .db 0xed,0x39,BBR - 892 - 893 ; CALL RPAGE ; SET PAGE TO CP/M RAM - 894 - 895 ; EI ; RE-ENABLE INTERRUPTS - 896 - 024F 2Ar66s05 897 ld hl,(DMAAD) ; load hl with dma addr - 0252 5D 898 ld e,l - 0253 54 899 ld d,h ; get it into de - 0254 21r7Cs05 900 ld hl,#TMPBUF ; get rom/ram addr - 0257 01 80 00 901 ld bc,#128 - 025A ED B0 902 ldir - 903 - 025C 3E 00 904 ld a,#0 - 025E C9 905 RET - 906 - 025F 907 READ_ROM_DISK: - 025F F3 908 DI ; IF RAM, PROCEED WITH NORMAL TRACK/SECTOR READ - 0260 CDr98s03 909 CALL SECPAGE ; SETUP FOR READ OF RAM OR ROM DISK - 0263 CDrA6s03 910 CALL PAGERB ; SET PAGER WITH DRIVE AND TRACK - 911 - 0266 21r7Cs05 912 ld hl,#TMPBUF ; load hl with temp buf address - 0269 54 913 ld d,h - 026A 5D 914 ld e,l ; get it into de - 026B 2Ar6Ds05 915 ld hl,(SECST) ; rom/ram address - 026E 01 80 00 916 ld bc,#128 - 0271 ED B0 917 ldir - 918 - 919 ; - 920 ; NOW WITH THE ROM/RAM DATA IN THE BUFFER WE CAN NOW MOVE IT TO THE - 921 ; DMA ADDRESS (IN RAM) - 922 ; - 0273 CDrB9s03 923 CALL RPAGE ; SET PAGE TO CP/M RAM - 924 ; EI ; RE-ENABLE INTERRUPTS - 925 - 0276 2Ar66s05 926 ld hl,(DMAAD) ; load hl with dma address - 0279 5D 927 ld e,l - 027A 54 928 ld d,h - 027B 21r7Cs05 929 ld hl,#TMPBUF ; get rom/ram address - 027E 01 80 00 930 ld bc,#128 - 0281 ED B0 931 ldir - 932 - 0283 3E 00 933 ld a,#0 - 0285 C9 934 ret - 935 - 936 - 0286 937 WRITE_RAM_DISK: - 938 - 0286 21r7Cs05 939 ld hl,#TMPBUF ; load hl with temp buf address - 0289 54 940 ld d,h - 028A 5D 941 ld e,l - 028B 2Ar66s05 942 ld hl,(DMAAD) - 028E 01 80 00 943 ld bc,#128 - 0291 ED B0 944 ldir - 945 - 946 ; - 947 ; NOW THAT DATA IS IN THE TEMP BUF WE SET TO RAM PAGE - 948 ; FOR WRITE. - 949 ; - 0293 F3 950 DI - 0294 CDr98s03 951 CALL SECPAGE ; GET RAM PAGE WRITE ADDRESS - 952 - 0297 2Ar62s05 953 ld hl,(TRACK) - 954 - 029A 29 955 add hl,hl ; *2 multiply by 8 (4k segs) - 029B 29 956 add hl,hl ; *4 - 029C 29 957 add hl,hl ; *8 - 029D 7D 958 ld a,l ; get track in l - 959 - 960 ; out0 BBR ; select RAM bank - 961 ;dwg; .BYTE $ED,$39,BBR - 962 ;;dwg;; out0 BBR - 029E ED 39 79 963 .db 0xed,0x39,BBR - 964 - 02A1 2Ar6Ds05 965 ld hl,(SECST) ; load hl with dma addr (where to write to) - 02A4 54 966 ld d,h ; get it into de - 02A5 5D 967 ld e,l - 02A6 21r7Cs05 968 ld hl,#TMPBUF ; get temp buffer address - 02A9 01 80 00 969 ld bc,#128 - 02AC ED B0 970 ldir - 971 - 02AE 3E 00 972 ld a,#0 ; return to system bank - 973 - 974 ; out0 BBR ; select RAM bank - 975 ;dwg; .BYTE $ED,$39,BBR - 976 ;;dwg;; out0 BBR - 02B0 ED 39 79 977 .db 0xed,0x39,BBR - 978 - 979 ; EI - 980 ; RE-ENABLE INTERRUPTS - 02B3 3E 00 981 ld a,#0 - 02B5 C9 982 ret - 983 - 984 ;------------------------------------------------------------------- - 985 - 986 ; Logical disk drivers - 987 - 02B6 988 READ_HDPART1: - 989 - 02B6 21 01 00 990 ld hl,#1 ; init LBA offset sector lo word - 02B9 22r6Fs05 991 ld (LBA_OFFSET_LO),hl - 02BC 21 00 00 992 ld hl,#0 ; init LBA offset sector hi word - 02BF 22r71s05 993 ld (LBA_OFFSET_HI),hl - 02C2 C3rD5s02 994 JP READ_HDPARTX - 995 - 02C5 996 READ_HDPART2: - 02C5 21 01 40 997 ld hl,#0x4001 ; init LBA offset sector lo word - 02C8 22r6Fs05 998 ld (LBA_OFFSET_LO),hl - 02CB 21 00 00 999 ld hl,#0 ; init LBA offset sector hi word - 02CE 22r71s05 1000 ld (LBA_OFFSET_HI),hl - 02D1 C3rD5s02 1001 JP READ_HDPARTX - 1002 - 02D4 1003 READ_HDPART3: - 02D4 1004 READ_HDPART4: - 02D4 C9 1005 ret - 1006 - 1007 - 02D5 1008 READ_HDPARTX: - 1009 - 1010 ; BDOS TRACK PARAMETER (16 BITS) - 1011 ; BDOS SECTOR PARAMETER (16 BITS) - 1012 - 02D5 2Ar62s05 1013 ld hl,(TRACK) ; load track number (word) - 02D8 45 1014 ld b,l ; save lower 8 bits (tracks 0-255) - 02D9 2Ar64s05 1015 ld hl,(SECTOR) ; load sector number (word) - 02DC 60 1016 ld h,b ; hl is 8 bit track in h, 8 bit sector in l - 02DD CDrC4s03 1017 CALL CONVERT_IDE_SECTOR_CPM ; COMPUTE WHERE CP/M SECTOR IS ON THE - 1018 ; IDE PARTITION - 1019 - 1020 ; MAP COMPUTED IDE HD SECTOR TO LBA REGISTERS - 1021 - 1022 ; LBA REGISTERS STORE 28 BIT VALUE OF IDE HD SECTOR ADDRESS - 1023 - 02E0 3Ar73s05 1024 ld a,(LBA_TARGET_LO) ; load LBA reg 0 with sector addr to read - 02E3 32r77s05 1025 ld (IDE_LBA0),a - 02E6 3Ar74s05 1026 ld a,(LBA_TARGET_LO+1) ; load LBA reg 1 with sector addr t read - 02E9 32r78s05 1027 ld (IDE_LBA1),a - 02EC 3Ar75s05 1028 ld a,(LBA_TARGET_HI) ; load LBA reg 2 with sector addr to read - 02EF 32r79s05 1029 ld (IDE_LBA2),a - 02F2 3Ar76s05 1030 ld a,(LBA_TARGET_HI+1) ; load LBA reg 3 with sector addr to read - 02F5 E6 0F 1031 and a,#0b00001111 ; only lower 4 bits are valid - 02F7 C6 E0 1032 add a,#0b11100000 ; enable LBA bits 5:7=111 in IDE_LBA3 - 02F9 32r7As05 1033 ld (IDE_LBA3),a - 02FC CDrFCs03 1034 CALL IDE_READ_SECTOR ; READ THE IDE HARD DISK SECTOR - 1035 - 1036 ; NEED TO ADD ERROR CHECKING HERE, CARRY FLAG IS SET IF IDE_READ_SECTOR SUCCESSFUL! - 1037 - 1038 ; COMPUTE STARTING ADDRESS OF CP/M SECTOR IN READ IDE HD SECTOR BUFFER - 1039 - 02FF 21r7Cs05 1040 ld hl,#SECTOR_BUFFER ; load hl with sector buffer address - 1041 - 0302 3Ar7Bs05 1042 ld a,(SECTOR_INDEX) ; get the sector index (off in buff) - 1043 - 0305 CB 0F 1044 RRC a ; MOVE BIT 0 TO BIT 7 - 0307 CB 0F 1045 RRC a ; DO AGAIN - IN EFFECT MULTIPLY BY 64 - 1046 - 0309 16 00 1047 ld d,#0 ; put result as 16 value in de, upper byte in d is 0 - 1048 - 030B 5F 1049 ld e,a ; put addr offset in e - 1050 - 030C 19 1051 add hl,de ; multiply by 2, total mult is x 128 - 1052 - 030D 19 1053 add hl,de ; cp/m sect starting addr in IDE HD sector buffer - 1054 - 1055 ; COPY CP/M SECTOR TO BDOS DMA ADDRESS BUFFER - 1056 - 030E 54 1057 ld D,H ; TRANSFER HL REGISTERS TO DE - 030F 5D 1058 ld E,L - 0310 2Ar66s05 1059 ld hl,(DMAAD) ; LOAD HL WITH DMA ADDRESS - 0313 EB 1060 ex de,hl - 0314 01 80 00 1061 ld bc,#128 - 0317 ED B0 1062 ldir - 1063 - 1064 ; EI ; RE-ENABLE INTERRUPTS - 1065 - 0319 3E 00 1066 ld a,#0 ; return err code read successful a=0 - 031B C9 1067 ret - 1068 - 1069 - 1070 - 1071 - 1072 ;------------------------------------------------------------------- - 1073 - 1074 - 031C 1075 WRITE_HDPART1: - 1076 - 1077 ; DI ; DISABLE INTERRUPTS - 1078 - 031C 21 01 00 1079 ld hl,#1 ; init LBA offset sector lo word - 031F 22r6Fs05 1080 ld (LBA_OFFSET_LO),hl - 0322 21 00 00 1081 ld hl,#0 ; init LBA offset sector hi word - 0325 22r71s05 1082 ld (LBA_OFFSET_HI),hl - 0328 C3r3Bs03 1083 JP WRITE_HDPARTX - 1084 - 1085 - 032B 1086 WRITE_HDPART2: - 1087 - 1088 ; DI ; DISABLE INTERRUPTS - 1089 - 032B 21 01 40 1090 ld hl,#0x4001 ; init LBA offset sector lo word - 032E 22r6Fs05 1091 ld (LBA_OFFSET_LO),hl - 0331 21 00 00 1092 ld hl,#0 ; init LBA offset sector hi word - 0334 22r71s05 1093 ld (LBA_OFFSET_HI),hl - 0337 C3r3Bs03 1094 JP WRITE_HDPARTX - 1095 - 1096 ;------------------------------------------------------------------- - 1097 - 033A 1098 WRITE_HDPART3: ; STUB - 033A 1099 WRITE_HDPART4: ; STUB - 033A C9 1100 RET - 1101 - 1102 ;------------------------------------------------------------------- - 1103 - 1104 - 033B 1105 WRITE_HDPARTX: - 1106 - 1107 ; BDOS TRACK PARAMETER (16 BITS) - 1108 ; BDOS SECTOR PARAMETER (16 BITS) - 1109 - 033B 2Ar62s05 1110 ld hl,(TRACK) ; load track # (word) - 033E 45 1111 ld b,l ; save lower 8 bits (tracks 0-255) - 033F 2Ar64s05 1112 ld hl,(SECTOR) ; load sector # (word) - 0342 60 1113 ld h,b ; hl is 8 bit track in h, 8 bit sector in l - 1114 - 0343 CDrC4s03 1115 CALL CONVERT_IDE_SECTOR_CPM ; COMPUTE WHERE THE CP/M SECT IS ON THE - 1116 ; IDE PARTITION - 1117 - 1118 ; MAP COMPUTED IDE HD SECTOR TO LBA REGISTERS - 1119 ; LBA REGISTERS STORE 28 BIT VALUE OF IDE HD SECTOR ADDRESS - 1120 - 0346 3Ar73s05 1121 ld a,(LBA_TARGET_LO) ; load LBA reg 0 with sect addr to read - 0349 32r77s05 1122 ld (IDE_LBA0),a - 034C 3Ar74s05 1123 ld a,(LBA_TARGET_LO+1) ; load LBA reg 1 with sect addr to read - 034F 32r78s05 1124 ld (IDE_LBA1),a - 0352 3Ar75s05 1125 ld a,(LBA_TARGET_HI) ; load LBA reg 2 with sect addr to read - 0355 32r79s05 1126 ld (IDE_LBA2),a - 0358 3Ar76s05 1127 ld a,(LBA_TARGET_HI+1) ; load LBA reg 3 with sect addr to read - 035B E6 0F 1128 and a,#0b00001111 ; only lower four bits are valid - 035D C6 E0 1129 add a,#0b11100000 ; enable LBA bits 5:7=111 in IDE_LBA3 - 035F 32r7As05 1130 ld (IDE_LBA3),a - 0362 CDrFCs03 1131 CALL IDE_READ_SECTOR ; READ THE IDE HARD DISK SECTOR - 1132 - 1133 ; NEED TO ADD ERROR CHECKING HERE, - 1134 ; CARRY FLAG IS SET IF IDE_READ_SECTOR SUCCESSFUL! - 1135 - 1136 ; COMPUTE STARTING ADDRESS OF CP/M SECTOR IN READ IDE HD SECTOR BUFFER - 1137 - 0365 21r7Cs05 1138 ld hl,#SECTOR_BUFFER ; load hl with sector buffer address - 1139 - 0368 3Ar7Bs05 1140 ld a,(SECTOR_INDEX) ; get the sector index (off in buffer) - 1141 - 036B CB 0F 1142 RRC a ; MOVE BIT 0 TO BIT 7 - 036D CB 0F 1143 RRC a ; DO AGAIN - IN EFFECT MULTIPLY BY 64 - 1144 - 036F 16 00 1145 ld d,#0 ; put result as 16 bit value in de - 1146 ; UPPER BYTE IN D IS $00 - 0371 5F 1147 ld e,a ; put address offset in e - 1148 - 0372 19 1149 add hl,de ; cp/m starting addr in buffer - 1150 - 0373 19 1151 add hl,de ; *2, total mult is x128 - 1152 - 1153 ; KEEP CP/M SECTOR ADDRESS FOR LATER USE - 1154 ; COPY CP/M SECTOR FROM BDOS DMA ADDRESS BUFFER - 0374 22r6Ds05 1155 ld (SECST),hl - 1156 - 0377 2Ar6Ds05 1157 ld hl,(SECST) ; setup destination - 037A EB 1158 ex de,hl ; swap for next LHLD - 037B 2Ar66s05 1159 ld hl,(DMAAD) ; setup source - 037E 01 80 00 1160 ld bc,#128 ; byte count - 0381 ED B0 1161 ldir - 1162 - 1163 ; IDE HD SECTOR IS NOW UPDATED - 1164 ; WITH CURRENT CP/M SECTOR DATA SO WRITE TO DISK - 1165 - 0383 CDr15s04 1166 CALL IDE_WRITE_SECTOR ; WRITE THE UPDATED IDE HARD DISK SECTOR - 1167 - 1168 ; NEED TO ADD ERROR CHECKING HERE, - 1169 ; CARRY FLAG IS SET IF IDE_WRITE_SECTOR SUCCESSFUL! - 1170 - 1171 ; EI ; RE-ENABLE INTERRUPTS - 1172 - 0386 3E 00 1173 ld a,#0 ; return error code write successful a=0 - 0388 C9 1174 ret - 1175 - 1176 ;------------------------------------------------------------------- - 1177 - 1178 - 0389 1179 PRTMSG: - 0389 7E 1180 ld a,(hl) ; get char into A - 038A FE FF 1181 cp a,#END ; test for end byte - 038C CAr97s03 1182 jp z,PRTMSG1 ; jump if end byte is found - 038F 4F 1183 ld c,a ; put char to print in C for conout - 0390 CDr53s01 1184 CALL CONOUT ; SEND CHARACTER TO CONSOLE FROM REG C - 0393 23 1185 inc hl ; inc ptr to next char - 0394 C3r89s03 1186 JP PRTMSG ; TRANSMIT LOOP - 0397 1187 PRTMSG1: - 0397 C9 1188 ret - 1189 - 1190 - 1191 ; - 1192 ; UTILITY ROUTINE FOR SECTOR TO PAGE ADDRESS - 1193 ; USES HL AND CARRY - 1194 ; - 0398 1195 SECPAGE: - 0398 2Ar64s05 1196 ld hl,(SECTOR) - 039B 29 1197 add hl,hl ; * 2 - 039C 29 1198 add hl,hl ; * 4 - 039D 29 1199 add hl,hl ; * 8 - 039E 29 1200 add hl,hl ; * 16 - 039F 29 1201 add hl,hl ; * 32 - 03A0 29 1202 add hl,hl ; * 64 - 03A1 29 1203 add hl,hl ; * 128 - 03A2 22r6Ds05 1204 ld (SECST),hl ; save sector starting address - 03A5 C9 1205 ret - 1206 - 1207 ; - 1208 ; PAGER BYTE CREATION - 1209 ; ASSEMBLES DRIVE AND TRACK AND SENDS IT TO PAGER PORT - 1210 ; - 03A6 1211 PAGERB: - 03A6 2Ar62s05 1212 ld hl,(TRACK) - 03A9 7D 1213 ld a,l ; or l with acc to combine track and drive - 1214 ; out0 ACR+2 - 03AA ED 39 96 1215 .db 0xed,0x39,ACR+2 ; rom latch - 03AD 3E 00 1216 ld a,#0 ; switch in the rom - 1217 ; out0 ACR - 03AF ED 39 94 1218 .db 0xed,0x39,ACR - 03B2 32r69s05 1219 ld (PAGER),a ; save copy (just because) - 03B5 32r6As05 1220 ld (DB_PAGER),a ; save another copy for debug - 03B8 C9 1221 RET - 1222 - 1223 ; - 1224 ; RESET PAGER BACK TO RAM. - 1225 ; - 03B9 1226 RPAGE: - 1227 - 03B9 3E 80 1228 ld a,#0x80 ; deselect rom page - 1229 ; out0 ACR - 03BB ED 39 94 1230 .db 0xed,0x39,ACR - 1231 - 03BE 3E 00 1232 ld a,#0 ; set to RAM track 0 - 1233 ;dwg; STA PAGER ; SAVE COPY OF PAGER BYTE - 03C0 32r69s05 1234 ld (PAGER),a - 1235 - 03C3 C9 1236 RET - 1237 - 1238 - 03C4 1239 CONVERT_IDE_SECTOR_CPM: - 1240 - 1241 ; COMPUTES WHERE THE CP/M SECTOR IS IN THE IDE PARTITION - 1242 ; IDE HD SECTORS ARE 512 BYTES EACH, CP/M SECTORS ARE 128 BYTES EACH - 1243 ; MAXIMUM SIZE OF CP/M DISK IS 8 MB = 65536 (16 BITS) X 128 BYTES PER SECTOR - 1244 ; IDE HD PARTITION CAN HAVE AT MOST 16384 IDE SECTORS -> 65536 CP/M SECTORS - 1245 ; EACH IDE HD SECTOR CONTAINS 4 ADJACENT CP/M SECTORS - 1246 ; - 1247 ; - 1248 ; INPUT: - 1249 ; IDE HD PARTITION STARTING SECTOR NUMBER (FROM PARTITION TABLE) - 1250 ; - LOWER 16 BITS STORED IN LBA_OFFSET_LO - 1251 ; - UPPER 16 BITS STORED IN LBA_OFFSET_HI - 1252 ; PARTITION OFFSET IN HL (16 BITS) - 1253 ; - A UNIQUELY COMPUTED FUNCTION BASED ON GEOMETRY OF DISKS NUMBER OF - 1254 ; CP/M TRACKS AND SECTORS SPECIFIED IN DPB - 1255 ; - 1256 ; - 1257 ; OUTPUT: - 1258 ; IDE TARGET SECTOR (SENT TO IDE HD CONTROLLER FOR READ OPERATION) - 1259 ; - LOWER 16 BITS STORED IN LBA_TARGET_LO - 1260 ; - UPPER 16 BITS STORED IN LBA_TARGET_HI - 1261 ; CP/M TO IDE HD SECTOR MAPPING PARAMETER STORED IN SECTOR_INDEX - 1262 ; - 8 BIT VALUE WITH 4 LEGAL STATES (00, 01, 02, 04) WHICH IS - 1263 ; TO BE USED TO COMPUTE STARTING ADDRESS OF 128 BYTE CP/M SECTOR ONCE - 1264 ; 512 BYTE IDE HD SECTOR READ INTO MEMORY BUFFER - 1265 ; - 1266 - 1267 ; ROTATE WITH CARRY 16 BIT TRACK,SECTOR VALUE IN HL TO GET 14 BIT IDE HD - 1268 ; TARGET SECTOR IN PARTITION - 1269 ; KEEP LAST TWO BITS IN B FOR IDE HD SECTOR TO CP/M SECTOR TRANSLATION - 1270 - 1271 ; COMPUTE SECTOR_INDEX - 1272 - 1273 ;;dwg;; What is the point of this? the next inst sets A anyway?? - 03C4 AF 1274 xor a,a ; zero accumulator - 1275 - 03C5 7D 1276 ld a,l ; store the last 2 bits of l in b - 03C6 E6 03 1277 and a,#0b00000011 - 03C8 47 1278 ld b,a - 1279 - 03C9 32r7Bs05 1280 ld (SECTOR_INDEX),a ; locates the 128 cpm sector in buffer - 1281 - 1282 ; COMPUTE WHICH IDE HD SECTOR TO READ TO WITHIN 4 CP/M SECTORS - 1283 ; SHIFTS 16 BIT PARTITION OFFSET TO THE RIGHT 2 BITS AND ADDS RESULT TO - 1284 ; IDE HD PARTITION STARTING SECTOR - 1285 - 1286 ; SHIFT PARTITION OFFSET RIGHT 1 BIT - 1287 - 03CC 37 1288 scf ; set the carry flag, so we can clear it - 03CD 3F 1289 ccf ; Complement Carry Flag - 1290 - 03CE 7C 1291 ld a,h ; 16 bit rotate hl with carry - 03CF 1F 1292 rra - 03D0 67 1293 ld h,a ; rotate HL right 1 bit (divide by 2) - 03D1 7D 1294 ld a,l - 03D2 1F 1295 rra - 03D3 6F 1296 ld l,a - 1297 - 1298 ; SHIFT PARTITION OFFSET RIGHT 1 BIT - 1299 - 03D4 37 1300 scf - 03D5 3F 1301 ccf ; CLEAR CARRY FLAG - 1302 - 03D6 7C 1303 ld a,h ; 16 bit rotate HL with carry - 03D7 1F 1304 rra - 03D8 67 1305 ld H,A ; ROTATE HL RIGHT 1 BIT (DIVIDE BY 2) - 03D9 7D 1306 ld A,L - 03DA 1F 1307 rra - 03DB 6F 1308 ld L,A - 1309 - 1310 ; ADD RESULTING 14 BIT VALUE TO IDE HD PARTITION STARTING SECTOR - 1311 ; STORE RESULT IN IDE HD TARGET SECTOR PARAMETER - 1312 - 03DC 3Ar6Fs05 1313 ld a,(LBA_OFFSET_LO) ; 16 bit add of LBA_OFFSET_LO with hl - 03DF 85 1314 ADD L - 03E0 32r73s05 1315 ld (LBA_TARGET_LO),a - 03E3 3Ar70s05 1316 ld a,(LBA_OFFSET_LO+1) - 03E6 8C 1317 adc a,h - 03E7 32r74s05 1318 ld (LBA_TARGET_LO+1),a ; store overflow bit in carry - 03EA 21 00 00 1319 ld hl,#0 - 03ED 3Ar71s05 1320 ld a,(LBA_OFFSET_HI) ; 16 bit add w/carry of LBA_OFFSET_HI w/ - 03F0 8D 1321 adc a,l - 03F1 32r75s05 1322 ld (LBA_TARGET_HI),a - 03F4 3Ar72s05 1323 ld a,(LBA_OFFSET_HI+1) - 03F7 8C 1324 adc a,h - 03F8 32r76s05 1325 ld (LBA_TARGET_HI+1),a - 03FB C9 1326 RET - 1327 - 1328 - 1329 - 1330 ;------------------------------------------------------------------------------------ - 1331 ; Parallel port IDE driver - 1332 ; - 1333 ; - 1334 ; ----------------------------------------------------------------------------- - 1335 - 1336 ;read a sector, specified by the 4 bytes in "lba", - 1337 ;Return, acc is zero on success, non-zero for an error - 03FC 1338 IDE_READ_SECTOR: - 03FC CDr4Fs04 1339 call ide_wait_not_busy ;make sure drive is ready - 03FF CDr9Fs04 1340 call wr_lba ;tell it which sector we want - 1341 - 0402 3E 0F 1342 ld a,#ide_command ; select IDE reg - 0404 0E 20 1343 ld c,#ide_cmd_read - 0406 CDrEBs04 1344 call ide_write ;ask the drive to read it - 0409 CDr69s04 1345 call ide_wait_drq ;wait until it's got the data - 1346 ; bit 0,a - 1347 ; ani 1 - 1348 ; jnz get_err - 1349 - 040C 21r7Cs05 1350 ld hl,#SECTOR_BUFFER - 040F CDr77s04 1351 call read_data ;grab the data - 0412 3E 00 1352 ld a,#0 ; ? set successful return code ? - 1353 - 0414 C9 1354 ret - 1355 - 1356 - 1357 ;----------------------------------------------------------------------------- - 1358 - 1359 - 1360 ;write a sector, specified by the 4 bytes in "lba", - 1361 ;whatever is in the buffer gets written to the drive! - 1362 ;Return, acc is zero on success, non-zero for an error - 0415 1363 IDE_WRITE_SECTOR: - 0415 CDr4Fs04 1364 call ide_wait_not_busy ;make sure drive is ready - 0418 CDr9Fs04 1365 call wr_lba ;tell it which sector we want - 1366 - 041B 3E 0F 1367 ld a,#ide_command - 041D 0E 30 1368 ld c,#ide_cmd_write - 041F CDrEBs04 1369 call ide_write ;tell drive to write a sector - 0422 CDr69s04 1370 call ide_wait_drq ;wait unit it wants the data - 1371 - 1372 ; bit 0,a ; check for error returned - 1373 ; ani 1 - 1374 ; jnz get_err - 1375 - 0425 21r7Cs05 1376 ld hl,#SECTOR_BUFFER - 0428 CDr8Bs04 1377 call write_data ;give the data to the drive - 042B CDr4Fs04 1378 call ide_wait_not_busy ;wait until the write is complete - 1379 - 1380 ; bit 0,a - 1381 ; ani 1 - 1382 ; jnz get_err - 1383 - 1384 ; ld a,#0 ; SHOULD THIS BE HERE (Doug's idea) - 042E C9 1385 ret - 1386 - 1387 - 1388 ;----------------------------------------------------------------------------- - 1389 - 1390 ;--------ide_hard_reset--------------------------------------------------------------- - 1391 ;do a hard reset on the drive, by pulsing its reset pin. - 1392 ;this should usually be followed with a call to "ide_init". - 1393 ;------------------------------------------------------------------------------------------- - 042F 1394 ide_hard_reset: - 042F CDr05s05 1395 call set_ppi_rd - 0432 3E 80 1396 ld a,#ide_rst_line - 0434 D3 82 1397 out (IDECTL),a ; assert rst line on IDE interface - 0436 01 00 00 1398 ld bc,#0 - 0439 1399 rst_dly: - 0439 05 1400 dec b - 043A C2r39s04 1401 jp nz,rst_dly - 043D 3E 00 1402 ld a,#0 ; this could be XOR A,A (shorter) - 043F D3 82 1403 out (IDECTL),a ; deassert RST line on IDE interface - 0441 C9 1404 ret - 1405 - 1406 ;------------------------------------------------------------------------------ - 1407 ; IDE INTERNAL SUBROUTINES - 1408 ;------------------------------------------------------------------------------ - 1409 - 1410 - 1411 - 1412 ;---------------------------------------------------------------------------- - 1413 ;when an error occurs, we get bit 0 of A set from a call to ide_drq - 1414 ;or ide_wait_not_busy (which read the drive's status register). If - 1415 ;that error bit is set, we should jump here to read the drive's - 1416 ;explaination of the error, to be returned to the user. If for - 1417 ;some reason the error code is zero (shouldn't happen), we'll - 1418 ;return 255, so that the main program can always depend on a - 1419 ;return of zero to indicate success. - 0442 1420 get_err: - 0442 3E 09 1421 ld a,#ide_err - 0444 CDrCFs04 1422 call ide_read - 0447 79 1423 ld a,c - 0448 CAr4Cs04 1424 jp z,gerr2 - 044B C9 1425 ret - 044C 1426 gerr2: - 044C 3E FF 1427 ld a,#255 - 044E C9 1428 ret - 1429 - 1430 ;----------------------------------------------------------------------------- - 1431 - 044F 1432 ide_wait_not_busy: - 044F 3E 0F 1433 ld a,#ide_status ; wait for RDY bit to be set - 0451 CDrCFs04 1434 call ide_read - 0454 79 1435 ld a,c - 0455 E6 80 1436 and a,#0x80 ; isolate busy bit - 0457 C2r4Fs04 1437 jp nz,ide_wait_not_busy - 045A C9 1438 ret - 1439 - 1440 - 045B 1441 ide_wait_ready: - 045B 3E 0F 1442 ld a,#ide_status ; wait for RDY bit to be set - 045D CDrCFs04 1443 call ide_read - 0460 79 1444 ld a,c - 0461 E6 C0 1445 and a,#0b11000000 ; mask off busy and ready bits - 0463 EE 40 1446 xor a,#0b01000000 ; we want Busy(7) to be 0 and ready(6) to be 1 - 0465 C2r5Bs04 1447 jp nz,ide_wait_ready - 0468 C9 1448 ret - 1449 - 1450 ;Wait for the drive to be ready to transfer data. - 1451 ;Returns the drive's status in Acc - 0469 1452 ide_wait_drq: - 0469 3E 0F 1453 ld a,#ide_status ; waut for DRQ bit to be set - 046B CDrCFs04 1454 call ide_read - 046E 79 1455 ld a,c - 046F E6 88 1456 and a,#0b10001000 ; mask off busy(7) and DRQ(3) - 0471 EE 08 1457 xor a,#0b00001000 ; we want busy(7) to be 0 and DRQ (3) to be 1 - 0473 C2r69s04 1458 jp nz,ide_wait_drq - 0476 C9 1459 ret - 1460 - 1461 - 1462 - 1463 ;------------------------------------------------------------------------------ - 1464 - 1465 ;Read a block of 512 bytes (one sector) from the drive - 1466 ;and store it in memory @ HL - 0477 1467 read_data: - 0477 06 00 1468 ld b,#0 - 0479 1469 rdblk2: - 0479 C5 1470 push bc - 047A E5 1471 push hl - 047B 3E 08 1472 ld a,#ide_data - 047D CDrCFs04 1473 call ide_read ; read form data port - 0480 E1 1474 pop hl - 0481 71 1475 ld (hl),c - 0482 23 1476 inc hl - 0483 70 1477 ld (hl),b - 0484 23 1478 inc hl - 0485 C1 1479 pop bc - 0486 05 1480 dec b - 0487 C2r79s04 1481 jp nz,rdblk2 - 048A C9 1482 ret - 1483 - 1484 ;----------------------------------------------------------------------------- - 1485 - 1486 ;Write a block of 512 bytes (at HL) to the drive - 048B 1487 write_data: - 048B 06 00 1488 ld b,#0 - 048D 1489 wrblk2: - 048D C5 1490 push bc - 048E 4E 1491 ld c,(hl) ; lsb - 048F 23 1492 inc hl - 0490 46 1493 ld b,(hl) ; msb - 0491 23 1494 inc hl - 0492 E5 1495 push hl - 0493 3E 08 1496 ld a,#ide_data - 0495 CDrEBs04 1497 call ide_write - 0498 E1 1498 pop hl - 0499 C1 1499 pop bc - 049A 05 1500 dec b - 049B C2r8Ds04 1501 jp nz,wrblk2 - 049E C9 1502 ret - 1503 - 1504 - 1505 ;----------------------------------------------------------------------------- - 1506 - 1507 ;write the logical block address to the drive's registers - 049F 1508 wr_lba: - 049F 3Ar7As05 1509 ld a,(IDE_LBA0+3) ; MSB - 04A2 E6 0F 1510 and a,#0x0f - 04A4 F6 E0 1511 or a,#0xe0 - 04A6 4F 1512 ld c,a - 04A7 3E 0E 1513 ld a,#ide_head - 04A9 CDrEBs04 1514 call ide_write - 04AC 3Ar79s05 1515 ld a,(IDE_LBA0+2) - 04AF 4F 1516 ld c,a - 04B0 3E 0D 1517 ld a,#ide_cyl_msb - 04B2 CDrEBs04 1518 call ide_write - 04B5 3Ar78s05 1519 ld a,(IDE_LBA0+1) - 04B8 4F 1520 ld c,a - 04B9 3E 0C 1521 ld a,#ide_cyl_lsb - 04BB CDrEBs04 1522 call ide_write - 04BE 3Ar77s05 1523 ld a,(IDE_LBA0) ; LSB - 04C1 4F 1524 ld c,a - 04C2 3E 0B 1525 ld a,#ide_sector - 04C4 CDrEBs04 1526 call ide_write - 04C7 0E 01 1527 ld c,#1 - 04C9 3E 0A 1528 ld a,#ide_sec_cnt - 04CB CDrEBs04 1529 call ide_write - 1530 - 04CE C9 1531 ret - 1532 - 1533 ;------------------------------------------------------------------------------- - 1534 - 1535 ; Low Level I/O to the drive. These are the routines that talk - 1536 ; directly to the drive, via the 8255 chip. Normally a main - 1537 ; program would not call to these. - 1538 - 1539 ;Do a read bus cycle to the drive, using the 8255. - 1540 ;input A = ide regsiter address - 1541 ;output C = lower byte read from ide drive - 1542 ;output B = upper byte read from ide drive - 1543 - 04CF 1544 ide_read: - 04CF F5 1545 push af ; save register value - 04D0 CDr05s05 1546 call set_ppi_rd ; setup for a read cycle - 04D3 F1 1547 pop af ; restore register value - 04D4 D3 82 1548 out (IDECTL),a ;drive address onto control lines - 04D6 F6 40 1549 or a,#ide_rd_line ; assert RD pin - 04D8 D3 82 1550 out (IDECTL),a - 04DA F5 1551 push af ; save register value - 04DB DB 80 1552 in a,(IDELSB) ; read lower byte - 04DD 4F 1553 ld c,a ; save in c reg - 04DE DB 81 1554 in a,(IDEMSB) ; read upper byte - 04E0 47 1555 ld b,a ; save in reg b - 04E1 F1 1556 pop af ; restore reg value - 04E2 EE 40 1557 xor a,#ide_rd_line ; deassert RD signal - 04E4 D3 82 1558 out (IDECTL),a - 04E6 3E 00 1559 ld a,#0 ;; DWG SAYS couln't this be a 1 byter? - 04E8 D3 82 1560 out (IDECTL),a ;deassert all control pins - 04EA C9 1561 ret - 1562 - 1563 ;Do a write bus cycle to the drive, via the 8255 - 1564 ;input A = ide register address - 1565 ;input register C = lsb to write - 1566 ;input register B = msb to write - 1567 ; - 1568 - 1569 - 04EB 1570 ide_write: - 04EB F5 1571 push af ; save IDE reg valure - 04EC CDr0As05 1572 call set_ppi_wr ; setup for a write cycle - 04EF 79 1573 ld a,c ; get value to be written - 04F0 D3 80 1574 out (IDELSB),a - 04F2 78 1575 ld a,b ; get value to be written - 04F3 D3 81 1576 out (IDEMSB),a - 04F5 F1 1577 pop af ; restore saved IDE reg - 04F6 D3 82 1578 out (IDECTL),a ; drive address onto control lines - 04F8 F6 20 1579 or a,#ide_wr_line ; assert write pin - 04FA D3 82 1580 out (IDECTL),a - 04FC EE 20 1581 xor a,#ide_wr_line ; deasser write pin - 04FE D3 82 1582 out (IDECTL),a ;drive address onto control lines - 0500 3E 00 1583 ld a,#0 ;; DWG SAYS couldn't this be 1 byter? - 0502 D3 82 1584 out (IDECTL),a ; release bus signals - 0504 C9 1585 ret - 1586 - 1587 - 1588 ;----------------------------------------------------------------------------------- - 1589 ; ppi setup routine to configure the appropriate PPI mode - 1590 ; - 1591 ;------------------------------------------------------------------------------------ - 1592 - 0505 1593 set_ppi_rd: - 0505 3E 92 1594 ld a,#rd_ide_8255 - 0507 D3 83 1595 out (PIO1CONT),a ;config 8255 chip, read mode - 0509 C9 1596 ret - 1597 - 050A 1598 set_ppi_wr: - 050A 3E 80 1599 ld a,#wr_ide_8255 - 050C D3 83 1600 out (PIO1CONT),a ;config 8255 chip, write mode - 050E C9 1601 ret - 1602 - 1603 ;----------------------------------------------------------------------------- - 1604 ; End of PPIDE disk driver - 1605 ;------------------------------------------------------------------------------------ - 1606 - 1607 - 1608 ; TEXT STRINGS - 1609 - 050F 1610 TXT_RO_ERROR: - 050F 0D 0A 1611 .DB CR,LF - 0511 45 52 52 4F 52 3A 1612 .ascii "ERROR: WRITE TO READ ONLY DISK" - 20 57 52 49 54 45 - 20 54 4F 20 52 45 - 41 44 20 4F 4E 4C - 59 20 44 49 53 4B - 052F FF 1613 .DB END - 1614 - 0530 1615 TXT_STARTUP_MSG: - 0530 0D 0A 1616 .DB CR,LF - 0532 43 50 2F 4D 2D 38 1617 .ascii "CP/M-80 VERSION 2.2C FOR THE " - 30 20 56 45 52 53 - 49 4F 4E 20 32 2E - 32 43 20 46 4F 52 - 20 54 48 45 20 - 054F 4E 38 56 45 4D 20 1618 .ascii "N8VEM N8" - 4E 38 - 0557 20 28 50 50 49 44 1619 .ascii " (PPIDE)" - 45 29 - 055F 0D 0A 1620 .DB CR,LF - 0561 FF 1621 .DB END - 1622 - 1623 ; - 1624 ; THE REMAINDER OF THE CBIOS IS RESERVED UNINITIALIZED - 1625 ; DATA AREA, AND DOES NOT NEED TO BE A PART OF THE - 1626 ; SYSTEM MEMORY IMAGE - 1627 ; - 0562 1628 TRACK: .DS 2 ; TWO BYTES FOR TRACK # - 0564 1629 SECTOR: .DS 2 ; TWO BYTES FOR SECTOR # - 0566 1630 DMAAD: .DS 2 ; DIRECT MEMORY ADDRESS - 0568 1631 DISKNO: .DS 1 ; DISK NUMBER 0-15 - 1632 - 1633 - 0569 01 1634 PAGER: .DB 1 ; COPY OF PAGER BYTE - 1635 - 056A FF 1636 DB_PAGER: .db 0xff ; copy of pager byte - 1637 - 056B 1638 V_SECTOR: .DS 2 ; TWO BYTES FOR VIRTUAL SECTOR # - 056D 1639 SECST: .DS 2 ; SECTOR IN ROM/RAM START ADDRESS - 1640 - 1641 - 056F 00 00 1642 LBA_OFFSET_LO: .DW 0 ; IDE HD PART STARTING SECTOR (LOW 16 BITS) - 0571 00 00 1643 LBA_OFFSET_HI: .DW 0 ; IDE HD PART STARTING SECTOR (HI 16 BITS, 12 USED) - 0573 00 00 1644 LBA_TARGET_LO: .DW 0 ; IDE HD PART TARGET SECTOR (LOW 16 BITS) - 0575 00 00 1645 LBA_TARGET_HI: .DW 0 ; IDE HD PART TARGET SECTOR (HI 16 BITS, 12 USED) - 1646 - 0577 1647 IDE_LBA0: .DS 1 ;SET LBA 0:7 - 0578 1648 IDE_LBA1: .DS 1 ;SET LBA 8:15 - 0579 1649 IDE_LBA2: .DS 1 ;SET LBA 16:23 - 057A 1650 IDE_LBA3: .DS 1 ;LOWEST 4 BITS USED ONLY TO ENABLE LBA MODE - 1651 - 057B 00 1652 SECTOR_INDEX: .DB 0 ;WHERE 128 BYTE CP/M SECTOR IS IN 512 BYTE IDE HD SECTOR - 1653 - 1654 - 1655 ; - 1656 ; SCRATCH RAM AREA FOR BDOS USE - 1657 ; - 1658 ; Note: this can extend up to the beginning of the debug monitor however - 1659 ; there is a limitation in the amount of space available in the EPROM - 1660 ; - 1661 ;BEGDAT .EQU $ ;BEGINNING OF DATA AREA - 1662 ; - 1663 ; - 1664 - 057C 1665 SECTOR_BUFFER: .DS 512 ;Deblocking STORAGE FOR 512 BYTE IDE HD SECTOR - 1666 - 1667 ;dwg;TMPBUF .EQU SECTOR_BUFFER - 057C 1668 TMPBUF = SECTOR_BUFFER - 1669 - 077C 1670 DIRBF: .DS 128 ;SCRATCH DIRECTORY AREA - 07FC 1671 ALL00: .DS 4 ;ALLOCATION VECTOR 0 (DSM/8 = 1 BIT PER BLOCK) - 0800 1672 ALL01: .DS 32 ;ALLOCATION VECTOR 1 (225/8) - 0820 1673 ALL02: .DS 255 ;ALLOCATION VECTOR 2 (2040/8) - 091F 1674 ALL03: .DS 255 ;ALLOCATION VECTOR 3 (2040/8) - 0A1E 1675 ALL04: .DS 64 ;ALLOCATION VECTOR 4 (511/8) - 0A5E 1676 ALL05: .DS 64 ;ALLOCATION VECTOR 5 (495/8) - 1677 ; - 0A9E 1678 CHK00: .DS 0 ; NOT USED FOR FIXED MEDIA - 0A9E 1679 CHK01: .DS 0 ; NOT USED FOR FIXED MEDIA - 0A9E 1680 CHK02: .DS 0 ; NOT USED FOR FIXED MEDIA - 0A9E 1681 CHK03: .DS 0 ; NOT USED FOR FIXED MEDIA - 0A9E 1682 CHK04: .DS 0 ; NOT USED FOR FIXED MEDIA - 0A9E 1683 CHK05: .DS 0 ; NOT USED FOR FIXED MEDIA - 1684 - 1685 ; DOUG SAYS - THIS NEEDS TO BE DONE ANOTHER WAY NO ORGS IN REL SEG - 1686 ; - 1687 ; .ORG $F2FF - 1688 ; - 1689 ; F2FF - desired org - 1690 ; - E600 - BIOS ORG - 1691 ; ______ - 1692 ; 0CFF - necessary offset in this module - 1693 ; - 1694 ; 0CCF ; where we want to be - 1695 ; - 0AA9 ; where we are now - 1696 ; ______ - 1697 ; 0256 - adjustment to reach desired org in rel segment - 1698 ; - 1699 - 0A9E 1700 .ds 0x0256 ; THIS NEEDS TO BE ADJUSTED SO LASTBYTE IS AT 0CFF - 1701 - 0CF4 E5 1702 LASTBYTE: .DB 0xE5 ; note this is just to force out the last byte. - 1703 ; this address will actually fall within the - 1704 ; allocation vector block - 1705 - 0CF5 1706 _cbioshc_end:: - 1707 .area _CODE - 1708 .area _CABS diff --git a/doug/src/cbiosn8.rel b/doug/src/cbiosn8.rel deleted file mode 100755 index 8164539c..00000000 --- a/doug/src/cbiosn8.rel +++ /dev/null @@ -1,526 +0,0 @@ -XL -H 8 areas 4 global symbols -M cbioshc -O -mz80 -S .__.ABS. Def0000 -A _CODE size 0 flags 0 addr 0 -A _DATA size 0 flags 0 addr 0 -A _OVERLAY size 0 flags 0 addr 0 -A _HOME size 0 flags 0 addr 0 -A _GSINIT size 0 flags 0 addr 0 -A _GSFINAL size 0 flags 0 addr 0 -A _CBIOS size CF5 flags 0 addr 0 -S _cbioshc_start Def0000 -S _cbioshc_end Def0CF5 -S _cbioshc Def0000 -A _CABS size 0 flags 0 addr 0 -T 00 00 -R 00 00 06 00 -T 00 00 -R 00 00 06 00 -T 00 00 C3 DD 00 C3 F5 00 C3 2F 01 C3 -R 00 00 06 00 00 03 06 00 00 06 06 00 00 09 06 00 -T 0A 00 41 01 C3 53 01 C3 65 01 C3 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 13 00 6B 01 C3 6E 01 C3 C6 01 C3 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 1C 00 AF 01 C3 C9 01 C3 CF 01 C3 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 25 00 D8 01 C3 DE 01 C3 02 02 C3 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 2E 00 68 01 C3 D5 01 -R 00 00 06 00 00 02 06 00 00 05 06 00 -T 33 00 -R 00 00 06 00 -T 33 00 00 00 00 00 00 00 00 00 7C 07 83 00 9E 0A -R 00 00 06 00 00 0A 06 00 00 0C 06 00 00 0E 06 00 -T 41 00 FC 07 00 00 00 00 00 00 00 00 7C 07 CE 00 -R 00 00 06 00 00 02 06 00 00 0C 06 00 00 0E 06 00 -T 4F 00 9E 0A 5E 0A 00 00 00 00 00 00 00 00 7C 07 -R 00 00 06 00 00 02 06 00 00 04 06 00 00 0E 06 00 -T 5D 00 A1 00 9E 0A 20 08 00 00 00 00 00 00 00 00 -R 00 00 06 00 00 02 06 00 00 04 06 00 00 06 06 00 -T 6B 00 7C 07 B0 00 9E 0A -R 00 00 06 00 00 02 06 00 00 04 06 00 00 06 06 00 -T 71 00 1F 09 00 00 00 00 00 00 00 00 7C 07 BF 00 -R 00 00 06 00 00 02 06 00 00 0C 06 00 00 0E 06 00 -T 7F 00 9E 0A 1E 0A -R 00 00 06 00 00 02 06 00 00 04 06 00 -T 83 00 -R 00 00 06 00 -T 83 00 00 01 04 0F 01 DF 00 FF 00 F0 00 00 00 -R 00 00 06 00 -T 90 00 02 00 -R 00 00 06 00 -T 92 00 -R 00 00 06 00 -T 92 00 10 00 03 07 00 1F 00 1F 00 80 00 00 00 -R 00 00 06 00 -T 9F 00 05 00 -R 00 00 06 00 -T A1 00 -R 00 00 06 00 -T A1 00 00 01 05 1F 01 F7 07 FF 01 F0 00 00 00 -R 00 00 06 00 -T AE 00 01 00 -R 00 00 06 00 -T B0 00 -R 00 00 06 00 -T B0 00 00 01 05 1F 01 F7 07 FF 01 F0 00 00 00 -R 00 00 06 00 -T BD 00 01 00 -R 00 00 06 00 -T BF 00 -R 00 00 06 00 -T BF 00 00 01 04 0F 00 F1 01 FF 00 F0 00 00 00 -R 00 00 06 00 -T CC 00 01 00 -R 00 00 06 00 -T CE 00 -R 00 00 06 00 -T CE 00 00 01 04 0F 00 EF 01 FF 00 F0 00 00 00 -R 00 00 06 00 -T DB 00 01 00 -R 00 00 06 00 -T DD 00 -R 00 00 06 00 -T DD 00 F3 3E 80 D3 94 3E 01 32 04 00 3E 94 32 -R 00 00 06 00 -T EA 00 03 00 21 30 05 CD 89 03 C3 0E 01 -R 00 00 06 00 00 05 06 00 00 08 06 00 00 0B 06 00 -T F5 00 -R 00 00 06 00 -T F5 00 F3 31 80 00 AF D3 94 AF D3 96 21 00 09 11 -R 00 00 06 00 -T 03 01 00 D4 01 FF 15 ED B0 3E 80 D3 94 -R 00 00 06 00 -T 0E 01 -R 00 00 06 00 -T 0E 01 3E C3 32 00 00 21 03 00 22 01 00 32 05 00 -R 00 00 06 00 00 08 06 00 -T 1C 01 21 06 DC 22 06 00 01 80 00 CD D8 01 3A -R 00 00 06 00 00 0C 06 00 -T 29 01 04 00 4F C3 00 D4 -R 00 00 06 00 -T 2F 01 -R 00 00 06 00 -T 2F 01 3A 03 00 E6 03 FE 00 CA 91 01 FE 01 CA -R 00 00 06 00 00 0A 06 00 -T 3C 01 A9 01 C3 76 01 -R 00 00 06 00 00 02 06 00 00 05 06 00 -T 41 01 -R 00 00 06 00 -T 41 01 3A 03 00 E6 03 FE 00 CA 79 01 FE 01 CA -R 00 00 06 00 00 0A 06 00 -T 4E 01 A3 01 C3 71 01 -R 00 00 06 00 00 02 06 00 00 05 06 00 -T 53 01 -R 00 00 06 00 -T 53 01 3A 03 00 E6 03 FE 00 CA 85 01 FE 01 CA -R 00 00 06 00 00 0A 06 00 -T 60 01 A6 01 C3 74 01 -R 00 00 06 00 00 02 06 00 00 05 06 00 -T 65 01 -R 00 00 06 00 -T 65 01 C3 74 01 -R 00 00 06 00 00 03 06 00 -T 68 01 -R 00 00 06 00 -T 68 01 C3 76 01 -R 00 00 06 00 00 03 06 00 -T 6B 01 -R 00 00 06 00 -T 6B 01 C3 74 01 -R 00 00 06 00 00 03 06 00 -T 6E 01 -R 00 00 06 00 -T 6E 01 C3 71 01 -R 00 00 06 00 00 03 06 00 -T 71 01 -R 00 00 06 00 -T 71 01 3E 1A C9 -R 00 00 06 00 -T 74 01 -R 00 00 06 00 -T 74 01 79 C9 -R 00 00 06 00 -T 76 01 -R 00 00 06 00 -T 76 01 3E 01 C9 -R 00 00 06 00 -T 79 01 -R 00 00 06 00 -T 79 01 CD 91 01 FE 00 CA 79 01 ED 38 48 C9 -R 00 00 06 00 00 03 06 00 00 08 06 00 -T 85 01 -R 00 00 06 00 -T 85 01 CD 9A 01 A7 CA 85 01 79 ED 39 46 C9 -R 00 00 06 00 00 03 06 00 00 07 06 00 -T 91 01 -R 00 00 06 00 -T 91 01 ED 38 44 E6 80 C8 3E FF C9 -R 00 00 06 00 -T 9A 01 -R 00 00 06 00 -T 9A 01 ED 38 44 E6 02 C8 3E FF C9 -R 00 00 06 00 -T A3 01 -R 00 00 06 00 -T A3 01 C3 71 01 -R 00 00 06 00 00 03 06 00 -T A6 01 -R 00 00 06 00 -T A6 01 C3 74 01 -R 00 00 06 00 00 03 06 00 -T A9 01 -R 00 00 06 00 -T A9 01 C3 76 01 -R 00 00 06 00 00 03 06 00 -T AC 01 -R 00 00 06 00 -T AC 01 C3 76 01 -R 00 00 06 00 00 03 06 00 -T AF 01 -R 00 00 06 00 -T AF 01 21 00 00 79 FE 04 D0 79 32 68 05 6F 26 00 -R 00 00 06 00 00 0B 06 00 -T BD 01 29 29 29 29 11 33 00 19 C9 -R 00 00 06 00 00 07 06 00 -T C6 01 -R 00 00 06 00 -T C6 01 01 00 00 -R 00 00 06 00 -T C9 01 -R 00 00 06 00 -T C9 01 60 69 22 62 05 C9 -R 00 00 06 00 00 05 06 00 -T CF 01 -R 00 00 06 00 -T CF 01 60 69 22 64 05 C9 -R 00 00 06 00 00 05 06 00 -T D5 01 -R 00 00 06 00 -T D5 01 60 69 C9 -R 00 00 06 00 -T D8 01 -R 00 00 06 00 -T D8 01 69 60 22 66 05 C9 -R 00 00 06 00 00 05 06 00 -T DE 01 -R 00 00 06 00 -T DE 01 3A 68 05 FE 00 CA 2F 02 FE 01 CA 5F 02 FE -R 00 00 06 00 00 03 06 00 00 08 06 00 00 0D 06 00 -T EC 01 02 CA B6 02 FE 03 CA C5 02 FE 04 CA D4 02 -R 00 00 06 00 00 04 06 00 00 09 06 00 00 0E 06 00 -T FA 01 FE 05 CA D4 02 3E 01 C9 -R 00 00 06 00 00 05 06 00 -T 02 02 -R 00 00 06 00 -T 02 02 3A 68 05 FE 00 CA 86 02 FE 01 CA 26 02 FE -R 00 00 06 00 00 03 06 00 00 08 06 00 00 0D 06 00 -T 10 02 02 CA 1C 03 FE 03 CA 2B 03 FE 04 CA 3A 03 -R 00 00 06 00 00 04 06 00 00 09 06 00 00 0E 06 00 -T 1E 02 FE 05 CA 3A 03 3E 01 C9 -R 00 00 06 00 00 05 06 00 -T 26 02 -R 00 00 06 00 -T 26 02 21 0F 05 CD 89 03 3E 01 C9 -R 00 00 06 00 00 03 06 00 00 06 06 00 -T 2F 02 -R 00 00 06 00 -T 2F 02 F3 CD 98 03 2A 62 05 29 29 29 7D ED 39 79 -R 00 00 06 00 00 04 06 00 00 07 06 00 -T 3D 02 21 7C 05 54 5D 2A 6D 05 01 80 00 ED B0 3E -R 00 00 06 00 00 03 06 00 00 08 06 00 -T 4B 02 00 ED 39 79 2A 66 05 5D 54 21 7C 05 01 -R 00 00 06 00 00 07 06 00 00 0C 06 00 -T 58 02 80 00 ED B0 3E 00 C9 -R 00 00 06 00 -T 5F 02 -R 00 00 06 00 -T 5F 02 F3 CD 98 03 CD A6 03 21 7C 05 54 5D 2A -R 00 00 06 00 00 04 06 00 00 07 06 00 00 0A 06 00 -T 6C 02 6D 05 01 80 00 ED B0 CD B9 03 2A 66 05 5D -R 00 00 06 00 00 02 06 00 00 0A 06 00 00 0D 06 00 -T 7A 02 54 21 7C 05 01 80 00 ED B0 3E 00 C9 -R 00 00 06 00 00 04 06 00 -T 86 02 -R 00 00 06 00 -T 86 02 21 7C 05 54 5D 2A 66 05 01 80 00 ED B0 F3 -R 00 00 06 00 00 03 06 00 00 08 06 00 -T 94 02 CD 98 03 2A 62 05 29 29 29 7D ED 39 79 2A -R 00 00 06 00 00 03 06 00 00 06 06 00 -T A2 02 6D 05 54 5D 21 7C 05 01 80 00 ED B0 3E 00 -R 00 00 06 00 00 02 06 00 00 07 06 00 -T B0 02 ED 39 79 3E 00 C9 -R 00 00 06 00 -T B6 02 -R 00 00 06 00 -T B6 02 21 01 00 22 6F 05 21 00 00 22 71 05 C3 -R 00 00 06 00 00 06 06 00 00 0C 06 00 -T C3 02 D5 02 -R 00 00 06 00 00 02 06 00 -T C5 02 -R 00 00 06 00 -T C5 02 21 01 40 22 6F 05 21 00 00 22 71 05 C3 -R 00 00 06 00 00 06 06 00 00 0C 06 00 -T D2 02 D5 02 -R 00 00 06 00 00 02 06 00 -T D4 02 -R 00 00 06 00 -T D4 02 -R 00 00 06 00 -T D4 02 C9 -R 00 00 06 00 -T D5 02 -R 00 00 06 00 -T D5 02 2A 62 05 45 2A 64 05 60 CD C4 03 3A -R 00 00 06 00 00 03 06 00 00 07 06 00 00 0B 06 00 -T E1 02 73 05 32 77 05 3A 74 05 32 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T EA 02 78 05 3A 75 05 32 79 05 3A -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T F3 02 76 05 E6 0F C6 E0 32 7A 05 CD FC 03 21 -R 00 00 06 00 00 02 06 00 00 09 06 00 00 0C 06 00 -T 00 03 7C 05 3A 7B 05 CB 0F CB 0F 16 00 5F 19 19 -R 00 00 06 00 00 02 06 00 00 05 06 00 -T 0E 03 54 5D 2A 66 05 EB 01 80 00 ED B0 3E 00 C9 -R 00 00 06 00 00 05 06 00 -T 1C 03 -R 00 00 06 00 -T 1C 03 21 01 00 22 6F 05 21 00 00 22 71 05 C3 -R 00 00 06 00 00 06 06 00 00 0C 06 00 -T 29 03 3B 03 -R 00 00 06 00 00 02 06 00 -T 2B 03 -R 00 00 06 00 -T 2B 03 21 01 40 22 6F 05 21 00 00 22 71 05 C3 -R 00 00 06 00 00 06 06 00 00 0C 06 00 -T 38 03 3B 03 -R 00 00 06 00 00 02 06 00 -T 3A 03 -R 00 00 06 00 -T 3A 03 -R 00 00 06 00 -T 3A 03 C9 -R 00 00 06 00 -T 3B 03 -R 00 00 06 00 -T 3B 03 2A 62 05 45 2A 64 05 60 CD C4 03 3A -R 00 00 06 00 00 03 06 00 00 07 06 00 00 0B 06 00 -T 47 03 73 05 32 77 05 3A 74 05 32 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 50 03 78 05 3A 75 05 32 79 05 3A -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 59 03 76 05 E6 0F C6 E0 32 7A 05 CD FC 03 21 -R 00 00 06 00 00 02 06 00 00 09 06 00 00 0C 06 00 -T 66 03 7C 05 3A 7B 05 CB 0F CB 0F 16 00 5F 19 19 -R 00 00 06 00 00 02 06 00 00 05 06 00 -T 74 03 22 6D 05 2A 6D 05 EB 2A 66 05 01 80 00 ED -R 00 00 06 00 00 03 06 00 00 06 06 00 00 0A 06 00 -T 82 03 B0 CD 15 04 3E 00 C9 -R 00 00 06 00 00 04 06 00 -T 89 03 -R 00 00 06 00 -T 89 03 7E FE FF CA 97 03 4F CD 53 01 23 C3 89 03 -R 00 00 06 00 00 06 06 00 00 0A 06 00 00 0E 06 00 -T 97 03 -R 00 00 06 00 -T 97 03 C9 -R 00 00 06 00 -T 98 03 -R 00 00 06 00 -T 98 03 2A 64 05 29 29 29 29 29 29 29 22 6D 05 C9 -R 00 00 06 00 00 03 06 00 00 0D 06 00 -T A6 03 -R 00 00 06 00 -T A6 03 2A 62 05 7D ED 39 96 3E 00 ED 39 94 32 -R 00 00 06 00 00 03 06 00 -T B3 03 69 05 32 6A 05 C9 -R 00 00 06 00 00 02 06 00 00 05 06 00 -T B9 03 -R 00 00 06 00 -T B9 03 3E 80 ED 39 94 3E 00 32 69 05 C9 -R 00 00 06 00 00 0A 06 00 -T C4 03 -R 00 00 06 00 -T C4 03 AF 7D E6 03 47 32 7B 05 37 3F 7C 1F 67 7D -R 00 00 06 00 00 08 06 00 -T D2 03 1F 6F 37 3F 7C 1F 67 7D 1F 6F 3A 6F 05 85 -R 00 00 06 00 00 0D 06 00 -T E0 03 32 73 05 3A 70 05 8C 32 74 05 21 00 00 3A -R 00 00 06 00 00 03 06 00 00 06 06 00 00 0A 06 00 -T EE 03 71 05 8D 32 75 05 3A 72 05 8C 32 -R 00 00 06 00 00 02 06 00 00 06 06 00 00 09 06 00 -T F9 03 76 05 C9 -R 00 00 06 00 00 02 06 00 -T FC 03 -R 00 00 06 00 -T FC 03 CD 4F 04 CD 9F 04 3E 0F 0E 20 CD EB 04 CD -R 00 00 06 00 00 03 06 00 00 06 06 00 00 0D 06 00 -T 0A 04 69 04 21 7C 05 CD 77 04 3E 00 C9 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 15 04 -R 00 00 06 00 -T 15 04 CD 4F 04 CD 9F 04 3E 0F 0E 30 CD EB 04 CD -R 00 00 06 00 00 03 06 00 00 06 06 00 00 0D 06 00 -T 23 04 69 04 21 7C 05 CD 8B 04 CD -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 2C 04 4F 04 C9 -R 00 00 06 00 00 02 06 00 -T 2F 04 -R 00 00 06 00 -T 2F 04 CD 05 05 3E 80 D3 82 01 00 00 -R 00 00 06 00 00 03 06 00 -T 39 04 -R 00 00 06 00 -T 39 04 05 C2 39 04 3E 00 D3 82 C9 -R 00 00 06 00 00 04 06 00 -T 42 04 -R 00 00 06 00 -T 42 04 3E 09 CD CF 04 79 CA 4C 04 C9 -R 00 00 06 00 00 05 06 00 00 09 06 00 -T 4C 04 -R 00 00 06 00 -T 4C 04 3E FF C9 -R 00 00 06 00 -T 4F 04 -R 00 00 06 00 -T 4F 04 3E 0F CD CF 04 79 E6 80 C2 4F 04 C9 -R 00 00 06 00 00 05 06 00 00 0B 06 00 -T 5B 04 -R 00 00 06 00 -T 5B 04 3E 0F CD CF 04 79 E6 C0 EE 40 C2 5B 04 C9 -R 00 00 06 00 00 05 06 00 00 0D 06 00 -T 69 04 -R 00 00 06 00 -T 69 04 3E 0F CD CF 04 79 E6 88 EE 08 C2 69 04 C9 -R 00 00 06 00 00 05 06 00 00 0D 06 00 -T 77 04 -R 00 00 06 00 -T 77 04 06 00 -R 00 00 06 00 -T 79 04 -R 00 00 06 00 -T 79 04 C5 E5 3E 08 CD CF 04 E1 71 23 70 23 C1 05 -R 00 00 06 00 00 07 06 00 -T 87 04 C2 79 04 C9 -R 00 00 06 00 00 03 06 00 -T 8B 04 -R 00 00 06 00 -T 8B 04 06 00 -R 00 00 06 00 -T 8D 04 -R 00 00 06 00 -T 8D 04 C5 4E 23 46 23 E5 3E 08 CD EB 04 E1 C1 05 -R 00 00 06 00 00 0B 06 00 -T 9B 04 C2 8D 04 C9 -R 00 00 06 00 00 03 06 00 -T 9F 04 -R 00 00 06 00 -T 9F 04 3A 7A 05 E6 0F F6 E0 4F 3E 0E CD EB 04 3A -R 00 00 06 00 00 03 06 00 00 0D 06 00 -T AD 04 79 05 4F 3E 0D CD EB 04 3A 78 05 4F 3E 0C -R 00 00 06 00 00 02 06 00 00 08 06 00 00 0B 06 00 -T BB 04 CD EB 04 3A 77 05 4F 3E 0B CD EB 04 0E 01 -R 00 00 06 00 00 03 06 00 00 06 06 00 00 0C 06 00 -T C9 04 3E 0A CD EB 04 C9 -R 00 00 06 00 00 05 06 00 -T CF 04 -R 00 00 06 00 -T CF 04 F5 CD 05 05 F1 D3 82 F6 40 D3 82 F5 DB 80 -R 00 00 06 00 00 04 06 00 -T DD 04 4F DB 81 47 F1 EE 40 D3 82 3E 00 D3 82 C9 -R 00 00 06 00 -T EB 04 -R 00 00 06 00 -T EB 04 F5 CD 0A 05 79 D3 80 78 D3 81 F1 D3 82 F6 -R 00 00 06 00 00 04 06 00 -T F9 04 20 D3 82 EE 20 D3 82 3E 00 D3 82 C9 -R 00 00 06 00 -T 05 05 -R 00 00 06 00 -T 05 05 3E 92 D3 83 C9 -R 00 00 06 00 -T 0A 05 -R 00 00 06 00 -T 0A 05 3E 80 D3 83 C9 -R 00 00 06 00 -T 0F 05 -R 00 00 06 00 -T 0F 05 0D 0A 45 52 52 4F 52 3A 20 57 52 49 54 45 -R 00 00 06 00 -T 1D 05 20 54 4F 20 52 45 41 44 20 4F 4E 4C 59 20 -R 00 00 06 00 -T 2B 05 44 49 53 4B FF -R 00 00 06 00 -T 30 05 -R 00 00 06 00 -T 30 05 0D 0A 43 50 2F 4D 2D 38 30 20 56 45 52 53 -R 00 00 06 00 -T 3E 05 49 4F 4E 20 32 2E 32 43 20 46 4F 52 20 54 -R 00 00 06 00 -T 4C 05 48 45 20 4E 38 56 45 4D 20 4E 38 20 28 50 -R 00 00 06 00 -T 5A 05 50 49 44 45 29 0D 0A FF -R 00 00 06 00 -T 62 05 -R 00 00 06 00 -T 64 05 -R 00 00 06 00 -T 66 05 -R 00 00 06 00 -T 68 05 -R 00 00 06 00 -T 69 05 01 FF -R 00 00 06 00 -T 6B 05 -R 00 00 06 00 -T 6D 05 -R 00 00 06 00 -T 6F 05 00 00 00 00 00 00 00 00 -R 00 00 06 00 -T 77 05 -R 00 00 06 00 -T 78 05 -R 00 00 06 00 -T 79 05 -R 00 00 06 00 -T 7A 05 -R 00 00 06 00 -T 7B 05 00 -R 00 00 06 00 -T 7C 05 -R 00 00 06 00 -T 7C 07 -R 00 00 06 00 -T FC 07 -R 00 00 06 00 -T 00 08 -R 00 00 06 00 -T 20 08 -R 00 00 06 00 -T 1F 09 -R 00 00 06 00 -T 1E 0A -R 00 00 06 00 -T 5E 0A -R 00 00 06 00 -T 9E 0A -R 00 00 06 00 -T 9E 0A -R 00 00 06 00 -T 9E 0A -R 00 00 06 00 -T 9E 0A -R 00 00 06 00 -T 9E 0A -R 00 00 06 00 -T 9E 0A -R 00 00 06 00 -T 9E 0A -R 00 00 06 00 -T F4 0C E5 -R 00 00 06 00 -T F5 0C -R 00 00 06 00 diff --git a/doug/src/cbiosn8.s b/doug/src/cbiosn8.s deleted file mode 100755 index 79957ceb..00000000 --- a/doug/src/cbiosn8.s +++ /dev/null @@ -1,1708 +0,0 @@ -;-------------------------------------------------------- -; cbioshc.s derived from CPM22-HC.ASM by dwg 5/18-30/2011 -;-------------------------------------------------------- - .module cbioshc - .optsdcc -mz80 -;-------------------------------------------------------- -; Public variables in this module -;-------------------------------------------------------- - .globl _cbioshc -;-------------------------------------------------------- -; special function registers -;-------------------------------------------------------- -;-------------------------------------------------------- -; ram data -;-------------------------------------------------------- - .area _DATA -;-------------------------------------------------------- -; overlayable items in ram -;-------------------------------------------------------- - .area _OVERLAY -;-------------------------------------------------------- -; external initialized ram data -;-------------------------------------------------------- -;-------------------------------------------------------- -; global & static initialisations -;-------------------------------------------------------- - .area _HOME - .area _GSINIT - .area _GSFINAL - .area _GSINIT -;-------------------------------------------------------- -; Home -;-------------------------------------------------------- - .area _HOME - .area _HOME -;-------------------------------------------------------- -; code -;-------------------------------------------------------- - .area _CBIOS -_cbioshc_start:: -_cbioshc: - -;************************************************************** -;* -;* C B I O S f o r -;* -;* T e s t P r o t o t y p e -;* -;* by Andrew Lynch, with input from many sources -;* Updated 24-Mar-2009 Max Scane - changed seldsk: to not save bogus drive value -;* changed a: to be ram drive, B: to be rom disk -;* Updated 1-Jun-2010 Max Scane - Changed DPBs to be more sane -;* Updated 1-Jul-2010 Max Scane - Added PPIDE driver and conditionals -;* Updated April 2011 Max Scane - Adapted for the N8VEM Home Computer -;************************************************************** -; -; SKELETAL CBIOS FOR FIRST LEVEL OF CP/M 2.0 ALTERATION -; WITH MODS FOR CP/M ROMDISK AND RAMDISK. -; -; ENTIRELY IN 8080 MNEUMONICS (SO ASM CAN BE USED) -; BUT ASSUMES A Z80! (remove) -; - -MEM = 60 ; DOUGTEMP DOUGTEMP - - -;MSIZE .EQU 20 ;CP/M VERSION MEMORY SIZE IN KILOBYTES -;MSIZE .EQU 62 ;CP/M VERSION MEMORY SIZE IN KILOBYTES -; MEM defined in CPM22 above, line 0015 - -MSIZE = MEM ;CP/M VERSION MEMORY SIZE IN KILOBYTES - -; -; "BIAS" IS ADDRESS OFFSET FROM 3400H FOR MEMORY SYSTEMS -; THAN 16K (REFERRED TO AS "B" THROUGHOUT THE TEXT). -; - -BIAS = (MSIZE-20)*1024 - -CCP = 0x3400+BIAS ; base of ccp - -BDOS = CCP+0x0806 ; base of BDOS - -BIOS = CCP+0x1600 ; base of BIOS - -CDISK = 0x0004 ; current disk number 0=a,...,15=p - -; IOBYTE already defined in CPM22 above, line 0017 -;IOBYTE .EQU 0003H ;INTEL I/O BYTE - -; since the assembly has been broken into pieces, -; this symbols wasn't previously encountered. -; It could be exported from other module, but why? -IOBYTE = 0x0003 - -; -; CONSTANTS - - -END = 0x0FF - - -CR = 0x0d -LF = 0x0a - -DEFIOB = 0x94 ; default IOBYTE (TTY,RDR,PUN,LPT) - -; - -ROMSTART_MON = 0x0100 ; where the monitor is stored in ROM - -RAMTARG_MON = 0x0f800 ; where the monitor starts in RAM - -MOVSIZ_MON = 0x0800 ; monitor is 2K in length - -ROMSTART_CPM = 0x0900 ; where ccp+bdos+bios is stored in ROM - -RAMTARG_CPM = 0x0D400 ; where ccp+bdos+bios starts in RAM - -;dwg; INTERESTING - 0x15FF is 4K+1K+512-1, not 5KB -;dwg;MOVSIZ_CPM: .EQU $15FF ; CCP, BDOS IS 5KB IN LENGTH -MOVSIZ_CPM = 0x15FF ; ccp+bdos is 5KB in length - -HC_REG_BASE = 0x80 ; N8 I/I Regs $80-9F - -PPI1 = HC_REG_BASE+0x00 - -ACR = HC_REG_BASE+0x14 - -RMAP = ACR+2 - -IO_REG_BASE = 0x40 ; IO reg base offset for Z1x80 - -CNTLA0 = IO_REG_BASE+0x00 - -CNTLB0 = IO_REG_BASE+0x02 - -STAT0 = IO_REG_BASE+0x04 - -TDR0 = IO_REG_BASE+0x06 - -RDR0 = IO_REG_BASE+0x08 - -ASEXT0 = IO_REG_BASE+0x12 - -CBR = IO_REG_BASE+0x38 - -BBR = IO_REG_BASE+0x39 - -CBAR = IO_REG_BASE+0x3A - -; -; -; PIO 82C55 I/O IS ATTACHED TO THE FIRST IO BASE ADDRESS - -IDELSB = PPI1+0 ; LSB - -IDEMSB = PPI1+1 ; MSB - -IDECTL = PPI1+2 ; Control Signals - -PIO1CONT = PPI1+3 ; Control Byte PIO 82C55 - -; PPI control bytes for read and write to IDE drive - -rd_ide_8255 = 0b10010010 ; ide_8255_ctl out ide_8255_lsb/msb input - -wr_ide_8255 = 0b10000000 ; all three ports output - -;ide control lines for use with ide_8255_ctl. Change these 8 -;constants to reflect where each signal of the 8255 each of the -;ide control signals is connected. All the control signals must -;be on the same port, but these 8 lines let you connect them to -;whichever pins on that port. - -ide_a0_line = 0x01 ; direct from 8255 to ide interface - -ide_a1_line = 0x02 ; direct from 8255 to ide intereface - -ide_a2_line = 0x04 ; direct from 8255 to ide interface - -ide_cs0_line = 0x08 ; inverter between 8255 and ide interface - -ide_cs1_line = 0x10 ; inverter between 8255 and ide interface - -ide_wr_line = 0x20 ; inverter between 8255 and ide interface - -ide_rd_line = 0x40 ; inverter between 8255 and ide interface - -ide_rst_line = 0x80 ; inverter between 8255 and ide interface - -;------------------------------------------------------------------ -; More symbolic constants... these should not be changed, unless of -; course the IDE drive interface changes, perhaps when drives get -; to 128G and the PC industry will do yet another kludge. - -;some symbolic constants for the ide registers, which makes the -;code more readable than always specifying the address pins - -ide_data = ide_cs0_line -ide_err = ide_cs0_line + ide_a0_line -ide_sec_cnt = ide_cs0_line + ide_a1_line -ide_sector = ide_cs0_line + ide_a1_line + ide_a0_line -ide_cyl_lsb = ide_cs0_line + ide_a2_line -ide_cyl_msb = ide_cs0_line + ide_a2_line + ide_a0_line -ide_head = ide_cs0_line + ide_a2_line + ide_a1_line -ide_command = ide_cs0_line + ide_a2_line + ide_a1_line + ide_a0_line -ide_status = ide_cs0_line + ide_a2_line + ide_a1_line + ide_a0_line -ide_control = ide_cs1_line + ide_a2_line + ide_a1_line -ide_astatus = ide_cs1_line + ide_a2_line + ide_a1_line + ide_a0_line - -;IDE Command Constants. These should never change. - -ide_cmd_recal = 0x10 -ide_cmd_read = 0x20 -ide_cmd_write = 0x30 -ide_cmd_init = 0x91 -ide_cmd_id = 0x0ec -ide_cmd_spindown = 0xe0 -ide_cmd_spinup = 0xe1 - - -; .ORG BIOS ;ORIGIN OF THIS PROGRAM - - -;dwg;NSECTS .EQU ($-CCP)/128 ;WARM START SECTOR COUNT - -; -; JUMP VECTOR FOR INDIVIDUAL SUBROUTINES - - JP BOOT ;COLD START -WBOOTE: JP WBOOT ;WARM START - JP CONST ;CONSOLE STATUS - JP CONIN ;CONSOLE CHARACTER IN - JP CONOUT ;CONSOLE CHARACTER OUT - JP LIST ;LIST CHARACTER OUT (NULL ROUTINE) - JP PUNCH ;PUNCH CHARACTER OUT (NULL ROUTINE) - JP READER ;READER CHARACTER OUT (NULL ROUTINE) - JP HOME ;MOVE HEAD TO HOME POSITION - JP SELDSK ;SELECT DISK - JP SETTRK ;SET TRACK NUMBER - JP SETSEC ;SET SECTOR NUMBER - JP SETDMA ;SET DMA ADDRESS - JP READ ;READ DISK - JP WRITE ;WRITE DISK - JP LISTST ;RETURN LIST STATUS (NULL ROUTINE) - JP SECTRN ;SECTOR TRANSLATE - -; -; FIXED DATA TABLES FOR ALL DRIVES -; 0= RAMDISK, 1=ROMDISK, 2=HDPART1, 3=HDPART2 -; DISK PARAMETER HEADER FOR DISK 00 (RAM Disk) -DPBASE: - .DW 0x0000,0x0000 - .DW 0x0000,0x0000 - .DW DIRBF,DPBLK0 - .DW CHK00,ALL00 - -; DISK PARAMETER HEADER FOR DISK 05 (Large ROM Disk) - .DW 0x0000,0x0000 - .DW 0x0000,0x0000 - .DW DIRBF,DPBLK5 - .DW CHK05,ALL05 - - -; DISK PARAMETER HEADER FOR DISK 02 (8MB disk Partition) - .DW 0x0000,0x0000 - .DW 0x0000,0x0000 - .DW DIRBF,DPBLK2 - .DW CHK02,ALL02 - -; DISK PARAMETER HEADER FOR DISK 03 (8MB disk Partition) - .DW 0x0000,0x0000 - .DW 0x0000,0x0000 - .DW DIRBF,DPBLK3 - .DW CHK03,ALL03 - -; DISK PARAMETER HEADER FOR DISK 04 (??? third disk partition ???) - .DW 0x0000,0x0000 - .DW 0x0000,0x0000 - .DW DIRBF,DPBLK4 - .DW CHK04,ALL04 - -DPBLK0: ;DISK PARAMETER BLOCK (RAMDISK 512K, 448K usable) -SPT_1: .DW 256 ; 256 SECTORS OF 128 BYTES PER 32K TRACK -BSH_1: .DB 4 ; BLOCK SHIFT FACTOR (SIZE OF ALLOCATION BLOCK) -BLM_1: .DB 15 ; PART OF THE ALLOCATION BLOCK SIZE MATH -EXM_1: .DB 1 ; DEFINES SIZE OF EXTENT (DIRECTORY INFO) -DSM_1: .DW 223 ; BLOCKSIZE [2048] * NUMBER OF BLOCKS + 1 = DRIVE SIZE -DRM_1: .DW 255 ; NUMBER OF DIRECTORY ENTRIES -AL0_1: .DB 0b11110000 ; BIT MAP OF SPACE ALLOCATED TO DIRECTORY -AL1_1: .DB 0b00000000 ; DIRECTORY CAN HAVE UP TO 16 BLOCKS ALLOCATED -CKS_1: .DW 0 ; SIZE OF DIRECTORY CHECK [0 IF NON REMOVEABLE] -OFF_1: .DW 2 ; 2 TRACK RESERVED [FIRST 64K OF RAM] -; Note: changed to 2 tracks to skip over the 1st 64KB or RAM. - -DPBLK1: ;DISK PARAMETER BLOCK (ROMDISK 32KB WITH 16 2K TRACKS, 22K usable) -SPT_0: .DW 16 ; 16 SECTORS OF 128 BYTES PER 2K TRACK -BSH_0: .DB 3 ; BLOCK SHIFT FACTOR (SIZE OF ALLOCATION BLOCK) -BLM_0: .DB 7 ; PART OF THE ALLOCATION BLOCK SIZE MATH -EXM_0: .DB 0 ; DEFINES SIZE OF EXTENT (DIRECTORY INFO) -DSM_0: .DW 31 ; BLOCKSIZE [1024] * NUMBER OF BLOCKS + 1 = DRIVE SIZE -DRM_0: .DW 31 ; NUMBER OF DIRECTORY ENTRIES -AL0_0: .DB 0b10000000 ; BIT MAP OF SPACE ALLOCATED TO DIRECTORY -AL1_0: .DB 0b00000000 ; DIRECTORY CAN HAVE UP TO 16 BLOCKS ALLOCATED -CKS_0: .DW 0 ; SIZE OF DIRECTORY CHECK [0 IF NON REMOVEABLE] -OFF_0: .DW 5 ; FIRST 5 TRACKS TRACKS RESERVED (10K FOR SYSTEM) - ; SYSTEM IS ROM LOADER, CCP, BDOS, CBIOS, AND MONITOR - ; - ; IMPORTANT NOTE: TRACKS $00 - $04 OF 2K BYTES - ; EACH ARE MARKED WITH THE OFF_0 SET TO 5 AS - ; SYSTEM TRACKS. USABLE ROM DRIVE SPACE - ; STARTING AFTER THE FIFTH TRACK (IE, TRACK $05) - ; MOST LIKELY FIX TO THIS IS PLACING A DUMMY - ; FIRST 10K ROM CONTAINS THE ROM LOADER, MONITOR, - ; CCP, BDOS, BIOS, ETC (5 TRACKS * 2K EACH) - - -DPBLK2: ;DISK PARAMETER BLOCK (IDE HARD DISK 8MB) -SPT_2: .DW 256 ; 256 SECTORS OF 128 BYTES PER 32K TRACK -BSH_2: .DB 5 ; BLOCK SHIFT FACTOR (SIZE OF ALLOCATION BLOCK) -BLM_2: .DB 31 ; PART OF THE ALLOCATION BLOCK SIZE MATH -EXM_2: .DB 1 ; DEFINES SIZE OF EXTENT (DIRECTORY INFO) -DSM_2: .DW 2039 ; BLOCKSIZE [4096] * NUMBER OF BLOCKS + 1 = DRIVE SIZE - ; HD PARTITION 2 IS 16128 SECTORS LONG - ; AT 512 BYTES EACH WHICH IS - ; 2016 BLOCKS AT 4096 BYTES A PIECE. -DRM_2: .DW 511 ; NUMBER OF DIRECTORY ENTRIES -AL0_2: .DB 0b11110000 ; BIT MAP OF SPACE ALLOCATED TO DIRECTORY -AL1_2: .DB 0b00000000 ; DIRECTORY CAN HAVE UP TO 16 BLOCKS ALLOCATED -CKS_2: .DW 0 ; SIZE OF DIRECTORY CHECK [0 IF NON REMOVEABLE] -OFF_2: .DW 1 ; 1 TRACK (32K) RESERVED FOR SYSTEM - -DPBLK3: ;DISK PARAMETER BLOCK (IDE HARD DISK 8MB) -SPT_3: .DW 256 ; 256 SECTORS OF 128 BYTES PER 32K TRACK -BSH_3: .DB 5 ; BLOCK SHIFT FACTOR (SIZE OF ALLOCATION BLOCK) -BLM_3: .DB 31 ; PART OF THE ALLOCATION BLOCK SIZE MATH -EXM_3: .DB 1 ; DEFINES SIZE OF EXTENT (DIRECTORY INFO) -DSM_3: .DW 2039 ; BLOCKSIZE [4096] * NUMBER OF BLKS + 1 = DRIVE SIZE - ; HD PARTITION 3 IS 16128 SECTORS LONG - ; AT 512 BYTES EACH WHICH IS - ; 2016 BLOCKS AT 4096 BYTES A PIECE. -DRM_3: .DW 511 ; NUMBER OF DIRECTORY ENTRIES -AL0_3: .DB 0b11110000 ; BIT MAP OF SPACE ALLOCATED TO DIRECTORY -AL1_3: .DB 0b00000000 ; DIRECTORY CAN HAVE UP TO 16 BLOCKS ALLOCATED -CKS_3: .DW 0 ; SIZE OF DIRECTORY CHECK [0 IF NON REMOVEABLE] -OFF_3: .DW 1 ; 1 TRACK (32K) RESERVED FOR SYSTEM - -DPBLK4: ;DISK PARAMETER BLOCK (IDE HARD DISK 1024K) -SPT_4: .DW 256 ; 256 SECTORS OF 128 BYTES PER 32K TRACK -BSH_4: .DB 4 ; BLOCK SHIFT FACTOR (SIZE OF ALLOCATION BLOCK) -BLM_4: .DB 15 ; PART OF THE ALLOCATION BLOCK SIZE MATH -EXM_4: .DB 0 ; DEFINES SIZE OF EXTENT (DIRECTORY INFO) -DSM_4: .DW 497 ; BLKSIZE [2048] * NUMBER OF BLKS + 1 = DRIVE SIZE - ; HD PARTITION 4 IS 4032 SECTORS LONG - ; AT 512 BYTES EACH WHICH IS - ; 1008 BLOCKS AT 2048 BYTES A PIECE. - ; NOT USING ALL OF THE AVAILABLE SECTORS SINCE THIS - ; DRIVE IS INTENDED TO EMULATE A ROM DRIVE AND COPIED - ; INTO A ROM IN THE FUTURE. -DRM_4: .DW 255 ; NUMBER OF DIRECTORY ENTRIES -AL0_4: .DB 0b11110000 ; BIT MAP OF SPACE ALLOCATED TO DIRECTORY -AL1_4: .DB 0b00000000 ; DIRECTORY CAN HAVE UP TO 16 BLOCKS ALLOCATED -CKS_4: .DW 0 ; SIZE OF DIRECTORY CHECK [0 IF NON REMOVEABLE] -OFF_4: .DW 1 ; 1 TRACK RESERVED [FIRST 32K OF PARTITION] - -; -DPBLK5: ;DISK PARAMETER BLOCK (ROMDISK 1MB) -SPT_5: .DW 256 ; 256 SECTORS OF 128 BYTES PER 32K TRACK -BSH_5: .DB 4 ; BLOCK SHIFT FACTOR (SIZE OF ALLOCATION BLOCK) -BLM_5: .DB 15 ; PART OF THE ALLOCATION BLOCK SIZE MATH -EXM_5: .DB 0 ; DEFINES SIZE OF EXTENT (DIRECTORY INFO) -DSM_5: .DW 495 ; BLKSIZE [2048] * NUMBER OF BLKS +1 =DRIVE SIZE -;DSM_5: .DW 511 ; BLKSIZE [2048] * NUMBER OF BLKS +1 =DRIVE SIZE -DRM_5: .DW 255 ; NUMBER OF DIRECTORY ENTRIES -AL0_5: .DB 0b11110000 ; BIT MAP OF SPACE ALLOCATED TO DIRECTORY -AL1_5: .DB 0b00000000 ; DIR CAN HAVE UP TO 16 BLOCKS ALLOCATED -CKS_5: .DW 0 ; SIZE OF DIR CHECK [0 IF NON REMOVEABLE] -OFF_5: .DW 1 ; 1 TRACK RESERVED [FIRST 32K OF ROM] - -; -; END OF FIXED TABLES -; -; INDIVIDUAL SUBROUTINES TO PERFORM EACH FUNCTION - -BOOT: ;SIMPLEST CASE IS TO JUST PERFORM PARAMETER INITIALIZATION - di ; disable interrupts -; IM 1 ; SET INTERRUPT MODE 1 -; .DB $ED,$56 ; Z80 "IM 1" INSTRUCTION - - ld a,#0x80 - -; out0 ACR -; .BYTE $ED,$39,ACR ; ensure that the ROM is switched out - - out (ACR),a - - ld a,#1 - ld (CDISK),a ; select disk 0 - - ld a,#DEFIOB - ld (IOBYTE),a - -; ei ; enable interrupts - - ld hl,#TXT_STARTUP_MSG - CALL PRTMSG - - JP GOCPM ;INITIALIZE AND GO TO CP/M - -; -WBOOT: ;SIMPLEST CASE IS TO READ THE DISK UNTIL ALL SECTORS LOADED - ; WITH A ROMDISK WE SELECT THE ROM AND THE CORRECT PAGE [0] - ; THEN COPY THE CP/M IMAGE (CCP, BDOS, BIOS, MONITOR) TO HIGH RAM - ; LOAD ADDRESS. - - DI ; DISABLE INTERRUPT - - ld SP,#0x0080 ; use space below buffer for stack - -; IM 1 ; SET INTERRUPT MODE 1 -; .DB $ED,$56 ; Z80 "IM 1" INSTRUCTION - - xor a,a - - ; CHEAP ZERO IN ACC -; mvi a,00h ; switch in the ROM -; out0 ACR -; .BYTE $ED,$39,ACR - - out (ACR),a - - xor a,a - -; out0 RMAP -; .BYTE $ED,$39,$F6 - - out (RMAP),a ; set the rom map - - ; Just reload CCP and BDOS - - ld hl,#ROMSTART_CPM ; where in rom cp/m is stored (1st byte) - ld de,#RAMTARG_CPM ; where in ram to move ccp+BDOS to - ld bc,#MOVSIZ_CPM - ldir - - ld a,#0x80 - out (ACR),a - -; EI ; ENABLE INTERRUPTS - -; -; END OF LOAD OPERATION, SET PARAMETERS AND GO TO CP/M -GOCPM: - ;CPU RESET HANDLER - ld a,#0xC3 ; C32 is a jump opcode - ld (0x0000),a - ld hl,#WBOOTE ; address of warm boot - ld (0x0001),hl ; set addr field for jmp at 0 - - ld (0x0005),a ; for jump to bdos - ld hl,#BDOS - ld (0x0006),hl - - ld bc,#0x0080 ; default DMA address - CALL SETDMA - - ld a,(CDISK) ; get current disk number - ld c,a ; send to the ccp - JP CCP ;GO TO CP/M FOR FURTHER PROCESSING - - -; -;---------------------------------------------------------------------------------------------------------------------- -; N8VEM Home computer I/O handlers -; -; This implementation uses IOBYTE and allocates devices as follows: -; -; TTY - Driver for the Z180 ASCI port 0 -; CRT - Driver for the -; UC1 - Driver for the -; xxx - Driver for the -; -; Logical device drivers - these pass control to the physical -; device drivers depending on the value of the IOBYTE -; - -CONST: ;CONSOLE STATUS, RETURN 0FFH IF CHARACTER READY, 00H IF NOT - - ld a,(IOBYTE) - and a,#3 - cp #0 - jp z,TTYISTS - - cp #1 - jp z,CRTISTS - - jp NULLSTS - - - - -CONIN: ;CONSOLE CHARACTER INTO REGISTER A - ld a,(IOBYTE) - and a,#3 - cp #0 - jp z,TTYIN - cp #1 - jp z,CRTIN - jp NULLIN - - -CONOUT: ;CONSOLE CHARACTER OUTPUT FROM REGISTER C - ld a,(IOBYTE) - and a,#3 ; isolate console bits - cp #0 - jp z,TTYOUT - cp #1 - jp z,CRTOUT - jp NULLOUT - -LIST: ;LIST CHARACTER FROM REGISTER C - jp NULLOUT - - - -LISTST: ;RETURN LIST STATUS (0 IF NOT READY, 1 IF READY) - jp NULLSTS - - ; -PUNCH: ;PUNCH CHARACTER FROM REGISTER C - jp NULLOUT - -; -READER: ;READ CHARACTER INTO REGISTER A FROM READER DEVICE - - jp NULLIN ; currently not used - - - -;---------------------------------------------------------------------------------------------------------------------------------------- -; -; Here are the physical io device drivers -; -; Null driver - this is a dummy driver for the NULL device - -NULLIN: - ld a,#0x1a - ret - -NULLOUT: - ld a,c - ret - -NULLSTS: - ld a,#1 - ret - -; -;--------------------------------------------------------------------------------------------------------------------------------------------- -; -; TTY Driver (programmed i/o) this is the driver for the Home Computer console port -; -TTYIN: - CALL TTYISTS; IS A CHAR READY TO BE READ FROM UART? - cp #0 - jp z,TTYIN - -; IN0 A,(RDR0) - -;dwg; .BYTE $ED,$38,RDR0 - .byte 0xED,0x38,RDR0 - - ret - -TTYOUT: - call TTYOSTS - and a,a - jp z,TTYOUT ; if not repeat - - ld a,c ; get to accum - -; OUT0 (TDR0),A - .byte 0xed,0x39,TDR0 - - ret - -TTYISTS: -; IN0 A,(STAT0) -;dwg; .BYTE $ED,$38,STAT0 -;;dwg;; in0 a,(STAT0) - .byte 0xed,0x38,STAT0 - - and a,#0x80 - ret z ; is there a char ready? 0=no 1=yes - ld a,#0xff - ret ; NO, LEAVE $00 IN A AND RETURN - -TTYOSTS: -; IN0 A,(STAT0) -;dwg; .BYTE $ED,$38,STAT0 -;;dwg;; in0 a,(STAT0) - .byte 0xed,0x38,STAT0 - - and a,#2 - ret z - ld a,#0xff - - ret ; NO, LEAVE $00 IN A AND RETURN -;--------------------------------------------------------------------------------------------------------------------------------------------- -; CRT Driver - This is the driver for the Prop VDU -; - -CRTIN: - jp NULLIN - -CRTOUT: - jp NULLOUT - -CRTISTS: - jp NULLSTS - -CRTOSTS: - jp NULLSTS - - -;--------------------------------------------------------------------------------------------------------------------------------------------- - ;; -; I/O DRIVERS FOR THE DISK FOLLOW -; FOR NOW, WE WILL SIMPLY STORE THE PARAMETERS AWAY FOR USE -; IN THE READ AND WRITE SUBROUTINES -; - -; -; SELECT DISK GIVEN BY REGISTER C -; -SELDSK: - - ld hl,#0 ; error return code - - ld a,c - - cp a,#4 ; must be between 0 and 4 - ret nc ; no carry if 4,5,6,7 - ld a,c - ld (DISKNO),a ; save valid disk number - -; -; DISK NUMBER IS IN THE PROPER RANGE -; COMPUTE PROPER DISK PARAMETER HEADER ADDRESS - - ld l,a ; l = disk num 0,1,2,3,4 - ld h,#0 ; high order - add hl,hl ; * 2 - add hl,hl ; * 4 - add hl,hl ; * 8 - add hl,hl ; * 16 (size of each header) - ld de,#DPBASE - add hl,de ; hl = .DPBASE(DISKNO*16) - RET -; -HOME: ;MOVE TO THE TRACK 00 POSITION OF CURRENT DRIVE - ; TRANSLATE THIS CALL INTO A SETTRK CALL WITH PARAMETER 00 - - ld bc,#0 ; select track zero - -; CALL SETTRK -; RET ;WE WILL MOVE TO 00 ON FIRST READ/WRITE - ; FALL THROUGH TO SETTRK TO STORE VALUE - -SETTRK: ;SET TRACK GIVEN BY REGISTER BC - ld h,b - ld l,c - ld (TRACK),hl - RET -; -SETSEC: ;SET SECTOR GIVEN BY REGISTER BC - ld h,b - ld l,c - ld (SECTOR),hl - RET -; -; TRANSLATE THE SECTOR GIVEN BY BC USING THE -; TRANSLATE TABLE GIVEN BY DE -; ONLY USED FOR FLOPPIES! FOR ROMDISK/RAMDISK IT'S 1:1 -; DO THE NEXT ROUTINE IS A NULL (RETURNS THE SAME) -SECTRN: - ld h,b - ld l,c - RET -; - -SETDMA: ;SET DMA ADDRESS GIVEN BY REGISTERS B AND C - ld l,c - ld h,b - ld (DMAAD),hl - RET - -; READ DISK -; USES DE,DL, BC, ACC FLAGS -; Z80 COULD USE BLOCK MOVE [LDIR] BUT WRITTEN IN 8080 -READ: -; DI ; DISABLE INTERRUPTS - - ld a,(DISKNO) - ; FIND OUT WHICH DRIVE IS BEING REQUESTED - ; ARE WE READING RAM OR ROM? - cp #0 - jp z,READ_RAM_DISK - - cp #1 - jp z,READ_ROM_DISK - - cp #2 - jp z,READ_HDPART1 - - cp #3 - jp z,READ_HDPART2 ; READ FROM 8 MB IDE HD, PARTITION 2 - - cp #4 - jp z,READ_HDPART3 ; READ FROM 1 MB IDE HD, PARTITION 4 - - cp #5 - jp z,READ_HDPART4 ; READ FROM 1 MB IDE HD, PARTITION 5 - - ld a,#1 ; BDOS WILL ALSO PRINT ITS OWN ERROR MESSAGE - ret - - -; -; WRITE DISK -; -WRITE: -; DI ; DISABLE INTERRUPTS - - ld a,(DISKNO) ; get drive - -; ORA A ; SET FLAGS - - cp #0 ; find out which drive is being requested - - jp z,WRITE_RAM_DISK ; write to 448K ram disk - - cp #1 - jp z,RDONLY ; jump to read only routine - - ; READ ONLY, FROM 22K EEPROM DISK, ERROR ON WRITE - cp #2 - jp z,WRITE_HDPART1 ; write to 8MB IDE HD, Part 2 - - cp #3 - jp z,WRITE_HDPART2 ; write to 8MB IDE HD, Part 3 - - cp #4 - jp z,WRITE_HDPART3 ; write to 1MB IDE HD, Part 4 - - cp #5 - jp z,WRITE_HDPART4 ; write to 1MB IDE HD Part 5 - - - ; IF NONE OF THE OTHER DISKS, IT MUST BE - ; THE RAM DISK, SO FALL THROUGH - - ld a,#1 ; send bad sector error back - ; BDOS WILL ALSO PRINT ITS OWN ERROR MESSAGE - ret - - - -RDONLY: -; -; HANDLE WRITE TO READ ONLY -; -; SENDS A MESSAGE TO TERMINAL THAT ROM DRIVE IS NOT WRITEABLE -; DOES A PAUSE THEN RETURNS TO CPM WITH ERROR FLAGGED. THIS IS -; DONE TO ALLOW A POSSIBLE GRACEFUL EXIT (SOME APPS MAY PUKE). -; - - ; CODE TBD, PRINT A HEY WRONG DISK AND PAUSE 5 SEC AND - ; CONTINUE. - - ld hl,#TXT_RO_ERROR ; set hp --> error msg - CALL PRTMSG ; PRINT ERROR MESSAGE - - ld a,#1 ; send bad sector error back - ; BDOS WILL ALSO PRINT ITS OWN ERROR MESSAGE - ; ADD 5 SECOND PAUSE ROUTINE HERE - ret - -; -;-------------------------------------------------------------------------------------------------------------- -; -; DISK DRIVERS... -; -; DRIVER NEED TO DO SEVERAL THINGS FOR ROM AND RAM DISKS. -; - INTERRUPTS ARE NOT ALLOWED DURING LOW RAM/ROM ACCESS (DISABLE!) -; -TRANSLATE TRACK AND SECTOR INTO A POINTER TO WHERE THE 128 BYTE -; SECTOR BEGINS IN THE RAM/ROM -; -TRANSLATE THE DRIVE INTO A RAM/ROM SELECT, COMBINE WITH TRACK ADDRESS -; AND SEND TO THE MAP PORT. -; -COPY 128 BYTE FROM OR TO THE ROM/RAMDISK AND MEM POINTED TO BY DMA -; ADDRESS PREVIOUSLY STORED. -; -RESTORE MAP PORT TO PRIOR CONDITION BEFOR READ/WRITE -; -; - FIRST TRICK IS THAT WE MADE SECTORS 256 AS 256*128=32768. SO WE COPY -; THE LOW SECTOR ADDRESS TO THE LOW BYTE OF THE HL REGISTER AND THEN -; MULTIPLY BY 128. THIS RESULTS IN THE STARTING ADDR IN THE RAM OR ROM -; (0000 -> 7F80H) 32K PAGE. -; -; - TRICK TWO IS THE TRACK ADDRESS EQUALS THE 32K PAGE ADDRESS AND IS A -; DIRECT SELECT THAT CAN BE COPIED TO THE MAP PORT D0 THROUGH D5. D7 -; SELECTS THE DRIVE (ROM OR RAM). -; THAT MEANS THE LOW BYTE OF TRACK CONTAINS THE D0-D5 VALUE AND -; DISKNO HAS THE DRIVE SELECTED. WE FIRST COPY DISKNO TO ACC -; AND RIGHTSHIFT IT TO PLACE THAT IN BIT7, WE THEN ADD LOW BYTE OF -; TRACK TO ACC AND THEN SEND THAT TO THE MAP PORT. -; -; NOTE 1: A WRITE TO ROM SHOULD BE FLAGGED AS AN ERROR. -; NOTE 2: RAM MUST START AS A "FORMATTED DISK" IF BATTERY BACKED UP -; IT'S A DO ONCE AT COLD COLD START. IF NOT BATTERY BACKED UP -; IT WILL HAVE TO BE DONE EVERY TIME THE SYSTEM IS POWERED. -; FORMATTING THE RAM IS SIMPLE AS CLEARING THE DIRECTORY AREA -; TO A VALUE OF E5H (THE FIRST 8K OF TRACK 1 OR THE RAMDISK). -; IT COULD BE DONE AS A SIMPLE UTILITY PROGRAM STORED IN ROMDISK -; OR ANYTIME COLBOOT IS CALLED(LESS DESIREABLE). -; -; -WE NOW CAN COPY TO/FROM AS CORRECT FOR THE DEVICE 128 BYTES (SECTOR) -; TO OR FROM THE DMA ADDRESS. ALMOST! SINCE ROM OR RAM IS BEING PAGED -; WE HAVE TO COPY ANYTHING DESTINED FOR BELOW 8000H TO TEMP BUFFER -; THEN HANDLE THE PAGING. -; -; -; - LAST STEP IS TO RESTORE THE MAP PORT TO POINT TO THE RAM (TRACK 0) -; SO THE CP/M MEMORY MAP IS ALL RAM AGAIN AND NOT POINTING INTO THE -; DATA AREAS OR THE "DISK". -; SINCE THE RAM 0TH PAGE IS NOMINALLY THE LOW 32K OF RAM IN THE i -; SYSTEM WE CAN SEND A SIMPLE MVI A,80H ; OUT MPCL_ROM; MVI A,00H ; -; OUT MPCL_RAM. -; -; - THE READ OR WRITE OPERATION IS DONE. -; -; -; -; -; -; - - ; ACCESS ALGORITHM (ONLY APPLICABLE TO 32K ROM PART!) -READ_RAM_DISK: - DI ; IF RAM, PROCEED WITH NORMAL TRACK/SECTOR READ - CALL SECPAGE ; SETUP FOR READ OF RAM OR ROM DISK - - ld hl,(TRACK) ; multiply by 8 (4k segs) - -;dwg; dad h ; *2 - add hl,hl - -;dwg; dad h ; *4 - add hl,hl - -;dwg; dad h ; *8 - add hl,hl - -;dwg; MOV A,L ; get track in L - ld a,l - -; out0 BBR ; select RAM bank - -;dwg; .BYTE $ED,$39,BBR -;;dwg;; out0 BBR - .byte 0xed,0x39,BBR - - ld hl,#TMPBUF ; load hl with temp buf addr - ld d,h ; get it into de - ld e,l - ld hl,(SECST) ; rom/ram addr - ld bc,#128 - ldir - -; -; NOW WITH THE ROM/RAM DATA IN THE BUFFER WE CAN NOW MOVE IT TO THE -; DMA ADDRESS (IN RAM) -; - - ld a,#0 ; return to system bank - -; out0 BBR ; select RAM bank - -;dwg; .BYTE $ED,$39,BBR -;;dwg;; out0 BBR - .db 0xed,0x39,BBR - -; CALL RPAGE ; SET PAGE TO CP/M RAM - -; EI ; RE-ENABLE INTERRUPTS - - ld hl,(DMAAD) ; load hl with dma addr - ld e,l - ld d,h ; get it into de - ld hl,#TMPBUF ; get rom/ram addr - ld bc,#128 - ldir - - ld a,#0 - RET - -READ_ROM_DISK: - DI ; IF RAM, PROCEED WITH NORMAL TRACK/SECTOR READ - CALL SECPAGE ; SETUP FOR READ OF RAM OR ROM DISK - CALL PAGERB ; SET PAGER WITH DRIVE AND TRACK - - ld hl,#TMPBUF ; load hl with temp buf address - ld d,h - ld e,l ; get it into de - ld hl,(SECST) ; rom/ram address - ld bc,#128 - ldir - -; -; NOW WITH THE ROM/RAM DATA IN THE BUFFER WE CAN NOW MOVE IT TO THE -; DMA ADDRESS (IN RAM) -; - CALL RPAGE ; SET PAGE TO CP/M RAM -; EI ; RE-ENABLE INTERRUPTS - - ld hl,(DMAAD) ; load hl with dma address - ld e,l - ld d,h - ld hl,#TMPBUF ; get rom/ram address - ld bc,#128 - ldir - - ld a,#0 - ret - - -WRITE_RAM_DISK: - - ld hl,#TMPBUF ; load hl with temp buf address - ld d,h - ld e,l - ld hl,(DMAAD) - ld bc,#128 - ldir - -; -; NOW THAT DATA IS IN THE TEMP BUF WE SET TO RAM PAGE -; FOR WRITE. -; - DI - CALL SECPAGE ; GET RAM PAGE WRITE ADDRESS - - ld hl,(TRACK) - - add hl,hl ; *2 multiply by 8 (4k segs) - add hl,hl ; *4 - add hl,hl ; *8 - ld a,l ; get track in l - -; out0 BBR ; select RAM bank -;dwg; .BYTE $ED,$39,BBR -;;dwg;; out0 BBR - .db 0xed,0x39,BBR - - ld hl,(SECST) ; load hl with dma addr (where to write to) - ld d,h ; get it into de - ld e,l - ld hl,#TMPBUF ; get temp buffer address - ld bc,#128 - ldir - - ld a,#0 ; return to system bank - -; out0 BBR ; select RAM bank -;dwg; .BYTE $ED,$39,BBR -;;dwg;; out0 BBR - .db 0xed,0x39,BBR - -; EI - ; RE-ENABLE INTERRUPTS - ld a,#0 - ret - -;------------------------------------------------------------------- - -; Logical disk drivers - -READ_HDPART1: - - ld hl,#1 ; init LBA offset sector lo word - ld (LBA_OFFSET_LO),hl - ld hl,#0 ; init LBA offset sector hi word - ld (LBA_OFFSET_HI),hl - JP READ_HDPARTX - -READ_HDPART2: - ld hl,#0x4001 ; init LBA offset sector lo word - ld (LBA_OFFSET_LO),hl - ld hl,#0 ; init LBA offset sector hi word - ld (LBA_OFFSET_HI),hl - JP READ_HDPARTX - -READ_HDPART3: -READ_HDPART4: - ret - - -READ_HDPARTX: - - ; BDOS TRACK PARAMETER (16 BITS) - ; BDOS SECTOR PARAMETER (16 BITS) - - ld hl,(TRACK) ; load track number (word) - ld b,l ; save lower 8 bits (tracks 0-255) - ld hl,(SECTOR) ; load sector number (word) - ld h,b ; hl is 8 bit track in h, 8 bit sector in l - CALL CONVERT_IDE_SECTOR_CPM ; COMPUTE WHERE CP/M SECTOR IS ON THE - ; IDE PARTITION - - ; MAP COMPUTED IDE HD SECTOR TO LBA REGISTERS - - ; LBA REGISTERS STORE 28 BIT VALUE OF IDE HD SECTOR ADDRESS - - ld a,(LBA_TARGET_LO) ; load LBA reg 0 with sector addr to read - ld (IDE_LBA0),a - ld a,(LBA_TARGET_LO+1) ; load LBA reg 1 with sector addr t read - ld (IDE_LBA1),a - ld a,(LBA_TARGET_HI) ; load LBA reg 2 with sector addr to read - ld (IDE_LBA2),a - ld a,(LBA_TARGET_HI+1) ; load LBA reg 3 with sector addr to read - and a,#0b00001111 ; only lower 4 bits are valid - add a,#0b11100000 ; enable LBA bits 5:7=111 in IDE_LBA3 - ld (IDE_LBA3),a - CALL IDE_READ_SECTOR ; READ THE IDE HARD DISK SECTOR - -; NEED TO ADD ERROR CHECKING HERE, CARRY FLAG IS SET IF IDE_READ_SECTOR SUCCESSFUL! - - ; COMPUTE STARTING ADDRESS OF CP/M SECTOR IN READ IDE HD SECTOR BUFFER - - ld hl,#SECTOR_BUFFER ; load hl with sector buffer address - - ld a,(SECTOR_INDEX) ; get the sector index (off in buff) - - RRC a ; MOVE BIT 0 TO BIT 7 - RRC a ; DO AGAIN - IN EFFECT MULTIPLY BY 64 - - ld d,#0 ; put result as 16 value in de, upper byte in d is 0 - - ld e,a ; put addr offset in e - - add hl,de ; multiply by 2, total mult is x 128 - - add hl,de ; cp/m sect starting addr in IDE HD sector buffer - - ; COPY CP/M SECTOR TO BDOS DMA ADDRESS BUFFER - - ld D,H ; TRANSFER HL REGISTERS TO DE - ld E,L - ld hl,(DMAAD) ; LOAD HL WITH DMA ADDRESS - ex de,hl - ld bc,#128 - ldir - -; EI ; RE-ENABLE INTERRUPTS - - ld a,#0 ; return err code read successful a=0 - ret - - - - -;------------------------------------------------------------------- - - -WRITE_HDPART1: - -; DI ; DISABLE INTERRUPTS - - ld hl,#1 ; init LBA offset sector lo word - ld (LBA_OFFSET_LO),hl - ld hl,#0 ; init LBA offset sector hi word - ld (LBA_OFFSET_HI),hl - JP WRITE_HDPARTX - - -WRITE_HDPART2: - -; DI ; DISABLE INTERRUPTS - - ld hl,#0x4001 ; init LBA offset sector lo word - ld (LBA_OFFSET_LO),hl - ld hl,#0 ; init LBA offset sector hi word - ld (LBA_OFFSET_HI),hl - JP WRITE_HDPARTX - -;------------------------------------------------------------------- - -WRITE_HDPART3: ; STUB -WRITE_HDPART4: ; STUB - RET - -;------------------------------------------------------------------- - - -WRITE_HDPARTX: - - ; BDOS TRACK PARAMETER (16 BITS) - ; BDOS SECTOR PARAMETER (16 BITS) - - ld hl,(TRACK) ; load track # (word) - ld b,l ; save lower 8 bits (tracks 0-255) - ld hl,(SECTOR) ; load sector # (word) - ld h,b ; hl is 8 bit track in h, 8 bit sector in l - - CALL CONVERT_IDE_SECTOR_CPM ; COMPUTE WHERE THE CP/M SECT IS ON THE - ; IDE PARTITION - - ; MAP COMPUTED IDE HD SECTOR TO LBA REGISTERS - ; LBA REGISTERS STORE 28 BIT VALUE OF IDE HD SECTOR ADDRESS - - ld a,(LBA_TARGET_LO) ; load LBA reg 0 with sect addr to read - ld (IDE_LBA0),a - ld a,(LBA_TARGET_LO+1) ; load LBA reg 1 with sect addr to read - ld (IDE_LBA1),a - ld a,(LBA_TARGET_HI) ; load LBA reg 2 with sect addr to read - ld (IDE_LBA2),a - ld a,(LBA_TARGET_HI+1) ; load LBA reg 3 with sect addr to read - and a,#0b00001111 ; only lower four bits are valid - add a,#0b11100000 ; enable LBA bits 5:7=111 in IDE_LBA3 - ld (IDE_LBA3),a - CALL IDE_READ_SECTOR ; READ THE IDE HARD DISK SECTOR - - ; NEED TO ADD ERROR CHECKING HERE, - ; CARRY FLAG IS SET IF IDE_READ_SECTOR SUCCESSFUL! - - ; COMPUTE STARTING ADDRESS OF CP/M SECTOR IN READ IDE HD SECTOR BUFFER - - ld hl,#SECTOR_BUFFER ; load hl with sector buffer address - - ld a,(SECTOR_INDEX) ; get the sector index (off in buffer) - - RRC a ; MOVE BIT 0 TO BIT 7 - RRC a ; DO AGAIN - IN EFFECT MULTIPLY BY 64 - - ld d,#0 ; put result as 16 bit value in de - ; UPPER BYTE IN D IS $00 - ld e,a ; put address offset in e - - add hl,de ; cp/m starting addr in buffer - - add hl,de ; *2, total mult is x128 - - ; KEEP CP/M SECTOR ADDRESS FOR LATER USE - ; COPY CP/M SECTOR FROM BDOS DMA ADDRESS BUFFER - ld (SECST),hl - - ld hl,(SECST) ; setup destination - ex de,hl ; swap for next LHLD - ld hl,(DMAAD) ; setup source - ld bc,#128 ; byte count - ldir - - ; IDE HD SECTOR IS NOW UPDATED - ; WITH CURRENT CP/M SECTOR DATA SO WRITE TO DISK - - CALL IDE_WRITE_SECTOR ; WRITE THE UPDATED IDE HARD DISK SECTOR - - ; NEED TO ADD ERROR CHECKING HERE, - ; CARRY FLAG IS SET IF IDE_WRITE_SECTOR SUCCESSFUL! - -; EI ; RE-ENABLE INTERRUPTS - - ld a,#0 ; return error code write successful a=0 - ret - -;------------------------------------------------------------------- - - -PRTMSG: - ld a,(hl) ; get char into A - cp a,#END ; test for end byte - jp z,PRTMSG1 ; jump if end byte is found - ld c,a ; put char to print in C for conout - CALL CONOUT ; SEND CHARACTER TO CONSOLE FROM REG C - inc hl ; inc ptr to next char - JP PRTMSG ; TRANSMIT LOOP -PRTMSG1: - ret - - -; -; UTILITY ROUTINE FOR SECTOR TO PAGE ADDRESS -; USES HL AND CARRY -; -SECPAGE: - ld hl,(SECTOR) - add hl,hl ; * 2 - add hl,hl ; * 4 - add hl,hl ; * 8 - add hl,hl ; * 16 - add hl,hl ; * 32 - add hl,hl ; * 64 - add hl,hl ; * 128 - ld (SECST),hl ; save sector starting address - ret - -; -; PAGER BYTE CREATION -; ASSEMBLES DRIVE AND TRACK AND SENDS IT TO PAGER PORT -; -PAGERB: - ld hl,(TRACK) - ld a,l ; or l with acc to combine track and drive -; out0 ACR+2 - .db 0xed,0x39,ACR+2 ; rom latch - ld a,#0 ; switch in the rom -; out0 ACR - .db 0xed,0x39,ACR - ld (PAGER),a ; save copy (just because) - ld (DB_PAGER),a ; save another copy for debug - RET - -; -; RESET PAGER BACK TO RAM. -; -RPAGE: - - ld a,#0x80 ; deselect rom page -; out0 ACR - .db 0xed,0x39,ACR - - ld a,#0 ; set to RAM track 0 -;dwg; STA PAGER ; SAVE COPY OF PAGER BYTE - ld (PAGER),a - - RET - - -CONVERT_IDE_SECTOR_CPM: - - ; COMPUTES WHERE THE CP/M SECTOR IS IN THE IDE PARTITION - ; IDE HD SECTORS ARE 512 BYTES EACH, CP/M SECTORS ARE 128 BYTES EACH - ; MAXIMUM SIZE OF CP/M DISK IS 8 MB = 65536 (16 BITS) X 128 BYTES PER SECTOR - ; IDE HD PARTITION CAN HAVE AT MOST 16384 IDE SECTORS -> 65536 CP/M SECTORS - ; EACH IDE HD SECTOR CONTAINS 4 ADJACENT CP/M SECTORS - ; - ; - ; INPUT: - ; IDE HD PARTITION STARTING SECTOR NUMBER (FROM PARTITION TABLE) - ; - LOWER 16 BITS STORED IN LBA_OFFSET_LO - ; - UPPER 16 BITS STORED IN LBA_OFFSET_HI - ; PARTITION OFFSET IN HL (16 BITS) - ; - A UNIQUELY COMPUTED FUNCTION BASED ON GEOMETRY OF DISKS NUMBER OF - ; CP/M TRACKS AND SECTORS SPECIFIED IN DPB - ; - ; - ; OUTPUT: - ; IDE TARGET SECTOR (SENT TO IDE HD CONTROLLER FOR READ OPERATION) - ; - LOWER 16 BITS STORED IN LBA_TARGET_LO - ; - UPPER 16 BITS STORED IN LBA_TARGET_HI - ; CP/M TO IDE HD SECTOR MAPPING PARAMETER STORED IN SECTOR_INDEX - ; - 8 BIT VALUE WITH 4 LEGAL STATES (00, 01, 02, 04) WHICH IS - ; TO BE USED TO COMPUTE STARTING ADDRESS OF 128 BYTE CP/M SECTOR ONCE - ; 512 BYTE IDE HD SECTOR READ INTO MEMORY BUFFER - ; - - ; ROTATE WITH CARRY 16 BIT TRACK,SECTOR VALUE IN HL TO GET 14 BIT IDE HD - ; TARGET SECTOR IN PARTITION - ; KEEP LAST TWO BITS IN B FOR IDE HD SECTOR TO CP/M SECTOR TRANSLATION - - ; COMPUTE SECTOR_INDEX - -;;dwg;; What is the point of this? the next inst sets A anyway?? - xor a,a ; zero accumulator - - ld a,l ; store the last 2 bits of l in b - and a,#0b00000011 - ld b,a - - ld (SECTOR_INDEX),a ; locates the 128 cpm sector in buffer - - ; COMPUTE WHICH IDE HD SECTOR TO READ TO WITHIN 4 CP/M SECTORS - ; SHIFTS 16 BIT PARTITION OFFSET TO THE RIGHT 2 BITS AND ADDS RESULT TO - ; IDE HD PARTITION STARTING SECTOR - - ; SHIFT PARTITION OFFSET RIGHT 1 BIT - - scf ; set the carry flag, so we can clear it - ccf ; Complement Carry Flag - - ld a,h ; 16 bit rotate hl with carry - rra - ld h,a ; rotate HL right 1 bit (divide by 2) - ld a,l - rra - ld l,a - - ; SHIFT PARTITION OFFSET RIGHT 1 BIT - - scf - ccf ; CLEAR CARRY FLAG - - ld a,h ; 16 bit rotate HL with carry - rra - ld H,A ; ROTATE HL RIGHT 1 BIT (DIVIDE BY 2) - ld A,L - rra - ld L,A - - ; ADD RESULTING 14 BIT VALUE TO IDE HD PARTITION STARTING SECTOR - ; STORE RESULT IN IDE HD TARGET SECTOR PARAMETER - - ld a,(LBA_OFFSET_LO) ; 16 bit add of LBA_OFFSET_LO with hl - ADD L - ld (LBA_TARGET_LO),a - ld a,(LBA_OFFSET_LO+1) - adc a,h - ld (LBA_TARGET_LO+1),a ; store overflow bit in carry - ld hl,#0 - ld a,(LBA_OFFSET_HI) ; 16 bit add w/carry of LBA_OFFSET_HI w/ - adc a,l - ld (LBA_TARGET_HI),a - ld a,(LBA_OFFSET_HI+1) - adc a,h - ld (LBA_TARGET_HI+1),a - RET - - - -;------------------------------------------------------------------------------------ -; Parallel port IDE driver -; -; -; ----------------------------------------------------------------------------- - - ;read a sector, specified by the 4 bytes in "lba", - ;Return, acc is zero on success, non-zero for an error -IDE_READ_SECTOR: - call ide_wait_not_busy ;make sure drive is ready - call wr_lba ;tell it which sector we want - - ld a,#ide_command ; select IDE reg - ld c,#ide_cmd_read - call ide_write ;ask the drive to read it - call ide_wait_drq ;wait until it's got the data -; bit 0,a -; ani 1 -; jnz get_err - - ld hl,#SECTOR_BUFFER - call read_data ;grab the data - ld a,#0 ; ? set successful return code ? - - ret - - -;----------------------------------------------------------------------------- - - - ;write a sector, specified by the 4 bytes in "lba", - ;whatever is in the buffer gets written to the drive! - ;Return, acc is zero on success, non-zero for an error -IDE_WRITE_SECTOR: - call ide_wait_not_busy ;make sure drive is ready - call wr_lba ;tell it which sector we want - - ld a,#ide_command - ld c,#ide_cmd_write - call ide_write ;tell drive to write a sector - call ide_wait_drq ;wait unit it wants the data - -; bit 0,a ; check for error returned -; ani 1 -; jnz get_err - - ld hl,#SECTOR_BUFFER - call write_data ;give the data to the drive - call ide_wait_not_busy ;wait until the write is complete - -; bit 0,a -; ani 1 -; jnz get_err - -; ld a,#0 ; SHOULD THIS BE HERE (Doug's idea) - ret - - -;----------------------------------------------------------------------------- - -;--------ide_hard_reset--------------------------------------------------------------- - ;do a hard reset on the drive, by pulsing its reset pin. - ;this should usually be followed with a call to "ide_init". -;------------------------------------------------------------------------------------------- -ide_hard_reset: - call set_ppi_rd - ld a,#ide_rst_line - out (IDECTL),a ; assert rst line on IDE interface - ld bc,#0 -rst_dly: - dec b - jp nz,rst_dly - ld a,#0 ; this could be XOR A,A (shorter) - out (IDECTL),a ; deassert RST line on IDE interface - ret - -;------------------------------------------------------------------------------ -; IDE INTERNAL SUBROUTINES -;------------------------------------------------------------------------------ - - - -;---------------------------------------------------------------------------- - ;when an error occurs, we get bit 0 of A set from a call to ide_drq - ;or ide_wait_not_busy (which read the drive's status register). If - ;that error bit is set, we should jump here to read the drive's - ;explaination of the error, to be returned to the user. If for - ;some reason the error code is zero (shouldn't happen), we'll - ;return 255, so that the main program can always depend on a - ;return of zero to indicate success. -get_err: - ld a,#ide_err - call ide_read - ld a,c - jp z,gerr2 - ret -gerr2: - ld a,#255 - ret - -;----------------------------------------------------------------------------- - -ide_wait_not_busy: - ld a,#ide_status ; wait for RDY bit to be set - call ide_read - ld a,c - and a,#0x80 ; isolate busy bit - jp nz,ide_wait_not_busy - ret - - -ide_wait_ready: - ld a,#ide_status ; wait for RDY bit to be set - call ide_read - ld a,c - and a,#0b11000000 ; mask off busy and ready bits - xor a,#0b01000000 ; we want Busy(7) to be 0 and ready(6) to be 1 - jp nz,ide_wait_ready - ret - - ;Wait for the drive to be ready to transfer data. - ;Returns the drive's status in Acc -ide_wait_drq: - ld a,#ide_status ; waut for DRQ bit to be set - call ide_read - ld a,c - and a,#0b10001000 ; mask off busy(7) and DRQ(3) - xor a,#0b00001000 ; we want busy(7) to be 0 and DRQ (3) to be 1 - jp nz,ide_wait_drq - ret - - - -;------------------------------------------------------------------------------ - - ;Read a block of 512 bytes (one sector) from the drive - ;and store it in memory @ HL -read_data: - ld b,#0 -rdblk2: - push bc - push hl - ld a,#ide_data - call ide_read ; read form data port - pop hl - ld (hl),c - inc hl - ld (hl),b - inc hl - pop bc - dec b - jp nz,rdblk2 - ret - -;----------------------------------------------------------------------------- - - ;Write a block of 512 bytes (at HL) to the drive -write_data: - ld b,#0 -wrblk2: - push bc - ld c,(hl) ; lsb - inc hl - ld b,(hl) ; msb - inc hl - push hl - ld a,#ide_data - call ide_write - pop hl - pop bc - dec b - jp nz,wrblk2 - ret - - -;----------------------------------------------------------------------------- - - ;write the logical block address to the drive's registers -wr_lba: - ld a,(IDE_LBA0+3) ; MSB - and a,#0x0f - or a,#0xe0 - ld c,a - ld a,#ide_head - call ide_write - ld a,(IDE_LBA0+2) - ld c,a - ld a,#ide_cyl_msb - call ide_write - ld a,(IDE_LBA0+1) - ld c,a - ld a,#ide_cyl_lsb - call ide_write - ld a,(IDE_LBA0) ; LSB - ld c,a - ld a,#ide_sector - call ide_write - ld c,#1 - ld a,#ide_sec_cnt - call ide_write - - ret - -;------------------------------------------------------------------------------- - -; Low Level I/O to the drive. These are the routines that talk -; directly to the drive, via the 8255 chip. Normally a main -; program would not call to these. - - ;Do a read bus cycle to the drive, using the 8255. - ;input A = ide regsiter address - ;output C = lower byte read from ide drive - ;output B = upper byte read from ide drive - -ide_read: - push af ; save register value - call set_ppi_rd ; setup for a read cycle - pop af ; restore register value - out (IDECTL),a ;drive address onto control lines - or a,#ide_rd_line ; assert RD pin - out (IDECTL),a - push af ; save register value - in a,(IDELSB) ; read lower byte - ld c,a ; save in c reg - in a,(IDEMSB) ; read upper byte - ld b,a ; save in reg b - pop af ; restore reg value - xor a,#ide_rd_line ; deassert RD signal - out (IDECTL),a - ld a,#0 ;; DWG SAYS couln't this be a 1 byter? - out (IDECTL),a ;deassert all control pins - ret - - ;Do a write bus cycle to the drive, via the 8255 - ;input A = ide register address - ;input register C = lsb to write - ;input register B = msb to write - ; - - -ide_write: - push af ; save IDE reg valure - call set_ppi_wr ; setup for a write cycle - ld a,c ; get value to be written - out (IDELSB),a - ld a,b ; get value to be written - out (IDEMSB),a - pop af ; restore saved IDE reg - out (IDECTL),a ; drive address onto control lines - or a,#ide_wr_line ; assert write pin - out (IDECTL),a - xor a,#ide_wr_line ; deasser write pin - out (IDECTL),a ;drive address onto control lines - ld a,#0 ;; DWG SAYS couldn't this be 1 byter? - out (IDECTL),a ; release bus signals - ret - - -;----------------------------------------------------------------------------------- -; ppi setup routine to configure the appropriate PPI mode -; -;------------------------------------------------------------------------------------ - -set_ppi_rd: - ld a,#rd_ide_8255 - out (PIO1CONT),a ;config 8255 chip, read mode - ret - -set_ppi_wr: - ld a,#wr_ide_8255 - out (PIO1CONT),a ;config 8255 chip, write mode - ret - -;----------------------------------------------------------------------------- -; End of PPIDE disk driver -;------------------------------------------------------------------------------------ - - -; TEXT STRINGS - -TXT_RO_ERROR: - .DB CR,LF - .ascii "ERROR: WRITE TO READ ONLY DISK" - .DB END - -TXT_STARTUP_MSG: - .DB CR,LF - .ascii "CP/M-80 VERSION 2.2C FOR THE " - .ascii "N8VEM N8" - .ascii " (PPIDE)" - .DB CR,LF - .DB END - -; -; THE REMAINDER OF THE CBIOS IS RESERVED UNINITIALIZED -; DATA AREA, AND DOES NOT NEED TO BE A PART OF THE -; SYSTEM MEMORY IMAGE -; -TRACK: .DS 2 ; TWO BYTES FOR TRACK # -SECTOR: .DS 2 ; TWO BYTES FOR SECTOR # -DMAAD: .DS 2 ; DIRECT MEMORY ADDRESS -DISKNO: .DS 1 ; DISK NUMBER 0-15 - - -PAGER: .DB 1 ; COPY OF PAGER BYTE - -DB_PAGER: .db 0xff ; copy of pager byte - -V_SECTOR: .DS 2 ; TWO BYTES FOR VIRTUAL SECTOR # -SECST: .DS 2 ; SECTOR IN ROM/RAM START ADDRESS - - -LBA_OFFSET_LO: .DW 0 ; IDE HD PART STARTING SECTOR (LOW 16 BITS) -LBA_OFFSET_HI: .DW 0 ; IDE HD PART STARTING SECTOR (HI 16 BITS, 12 USED) -LBA_TARGET_LO: .DW 0 ; IDE HD PART TARGET SECTOR (LOW 16 BITS) -LBA_TARGET_HI: .DW 0 ; IDE HD PART TARGET SECTOR (HI 16 BITS, 12 USED) - -IDE_LBA0: .DS 1 ;SET LBA 0:7 -IDE_LBA1: .DS 1 ;SET LBA 8:15 -IDE_LBA2: .DS 1 ;SET LBA 16:23 -IDE_LBA3: .DS 1 ;LOWEST 4 BITS USED ONLY TO ENABLE LBA MODE - -SECTOR_INDEX: .DB 0 ;WHERE 128 BYTE CP/M SECTOR IS IN 512 BYTE IDE HD SECTOR - - -; -; SCRATCH RAM AREA FOR BDOS USE -; -; Note: this can extend up to the beginning of the debug monitor however -; there is a limitation in the amount of space available in the EPROM -; -;BEGDAT .EQU $ ;BEGINNING OF DATA AREA -; -; - -SECTOR_BUFFER: .DS 512 ;Deblocking STORAGE FOR 512 BYTE IDE HD SECTOR - -;dwg;TMPBUF .EQU SECTOR_BUFFER -TMPBUF = SECTOR_BUFFER - -DIRBF: .DS 128 ;SCRATCH DIRECTORY AREA -ALL00: .DS 4 ;ALLOCATION VECTOR 0 (DSM/8 = 1 BIT PER BLOCK) -ALL01: .DS 32 ;ALLOCATION VECTOR 1 (225/8) -ALL02: .DS 255 ;ALLOCATION VECTOR 2 (2040/8) -ALL03: .DS 255 ;ALLOCATION VECTOR 3 (2040/8) -ALL04: .DS 64 ;ALLOCATION VECTOR 4 (511/8) -ALL05: .DS 64 ;ALLOCATION VECTOR 5 (495/8) -; -CHK00: .DS 0 ; NOT USED FOR FIXED MEDIA -CHK01: .DS 0 ; NOT USED FOR FIXED MEDIA -CHK02: .DS 0 ; NOT USED FOR FIXED MEDIA -CHK03: .DS 0 ; NOT USED FOR FIXED MEDIA -CHK04: .DS 0 ; NOT USED FOR FIXED MEDIA -CHK05: .DS 0 ; NOT USED FOR FIXED MEDIA - -; DOUG SAYS - THIS NEEDS TO BE DONE ANOTHER WAY NO ORGS IN REL SEG -; -; .ORG $F2FF -; -; F2FF - desired org -; - E600 - BIOS ORG -; ______ -; 0CFF - necessary offset in this module -; -; 0CCF ; where we want to be -; - 0AA9 ; where we are now -; ______ -; 0256 - adjustment to reach desired org in rel segment -; - - .ds 0x0256 ; THIS NEEDS TO BE ADJUSTED SO LASTBYTE IS AT 0CFF - -LASTBYTE: .DB 0xE5 ; note this is just to force out the last byte. - ; this address will actually fall within the - ; allocation vector block - -_cbioshc_end:: - .area _CODE - .area _CABS diff --git a/doug/src/cbiosn8.sym b/doug/src/cbiosn8.sym deleted file mode 100755 index 200d3d98..00000000 --- a/doug/src/cbiosn8.sym +++ /dev/null @@ -1,96 +0,0 @@ - ASxxxx Assembler V02.00 + NoICE + SDCC mods + Flat24 (Zilog Z80 / Hitachi HD64180), page 1. - -Symbol Table - - .__.ABS.= 0000 G | ACR = 0094 | 6 AL0_0 009B R - 6 AL0_1 008C R | 6 AL0_2 00AA R | 6 AL0_3 00B9 R - 6 AL0_4 00C8 R | 6 AL0_5 00D7 R | 6 AL1_0 009C R - 6 AL1_1 008D R | 6 AL1_2 00AB R | 6 AL1_3 00BA R - 6 AL1_4 00C9 R | 6 AL1_5 00D8 R | 6 ALL00 07FC R - 6 ALL01 0800 R | 6 ALL02 0820 R | 6 ALL03 091F R - 6 ALL04 0A1E R | 6 ALL05 0A5E R | ASEXT0 = 0052 - BBR = 0079 | BDOS = DC06 | BIAS = A000 - BIOS = EA00 | 6 BLM_0 0095 R | 6 BLM_1 0086 R - 6 BLM_2 00A4 R | 6 BLM_3 00B3 R | 6 BLM_4 00C2 R - 6 BLM_5 00D1 R | 6 BOOT 00DD R | 6 BSH_0 0094 R - 6 BSH_1 0085 R | 6 BSH_2 00A3 R | 6 BSH_3 00B2 R - 6 BSH_4 00C1 R | 6 BSH_5 00D0 R | CBAR = 007A - CBR = 0078 | CCP = D400 | CDISK = 0004 - 6 CHK00 0A9E R | 6 CHK01 0A9E R | 6 CHK02 0A9E R - 6 CHK03 0A9E R | 6 CHK04 0A9E R | 6 CHK05 0A9E R - 6 CKS_0 009D R | 6 CKS_1 008E R | 6 CKS_2 00AC R - 6 CKS_3 00BB R | 6 CKS_4 00CA R | 6 CKS_5 00D9 R - CNTLA0 = 0040 | CNTLB0 = 0042 | 6 CONIN 0141 R - 6 CONOUT 0153 R | 6 CONST 012F R | 6 CONVERT_ 03C4 R - CR = 000D | 6 CRTIN 01A3 R | 6 CRTISTS 01A9 R - 6 CRTOSTS 01AC R | 6 CRTOUT 01A6 R | 6 DB_PAGER 056A R - DEFIOB = 0094 | 6 DIRBF 077C R | 6 DISKNO 0568 R - 6 DMAAD 0566 R | 6 DPBASE 0033 R | 6 DPBLK0 0083 R - 6 DPBLK1 0092 R | 6 DPBLK2 00A1 R | 6 DPBLK3 00B0 R - 6 DPBLK4 00BF R | 6 DPBLK5 00CE R | 6 DRM_0 0099 R - 6 DRM_1 008A R | 6 DRM_2 00A8 R | 6 DRM_3 00B7 R - 6 DRM_4 00C6 R | 6 DRM_5 00D5 R | 6 DSM_0 0097 R - 6 DSM_1 0088 R | 6 DSM_2 00A6 R | 6 DSM_3 00B5 R - 6 DSM_4 00C4 R | 6 DSM_5 00D3 R | END = 00FF - 6 EXM_0 0096 R | 6 EXM_1 0087 R | 6 EXM_2 00A5 R - 6 EXM_3 00B4 R | 6 EXM_4 00C3 R | 6 EXM_5 00D2 R - 6 GOCPM 010E R | HC_REG_B= 0080 | 6 HOME 01C6 R - IDECTL = 0082 | IDELSB = 0080 | IDEMSB = 0081 - 6 IDE_LBA0 0577 R | 6 IDE_LBA1 0578 R | 6 IDE_LBA2 0579 R - 6 IDE_LBA3 057A R | 6 IDE_READ 03FC R | 6 IDE_WRIT 0415 R - IOBYTE = 0003 | IO_REG_B= 0040 | 6 LASTBYTE 0CF4 R - 6 LBA_OFFS 0571 R | 6 LBA_OFFS 056F R | 6 LBA_TARG 0575 R - 6 LBA_TARG 0573 R | LF = 000A | 6 LIST 0165 R - 6 LISTST 0168 R | MEM = 003C | MOVSIZ_C= 15FF - MOVSIZ_M= 0800 | MSIZE = 003C | 6 NULLIN 0171 R - 6 NULLOUT 0174 R | 6 NULLSTS 0176 R | 6 OFF_0 009F R - 6 OFF_1 0090 R | 6 OFF_2 00AE R | 6 OFF_3 00BD R - 6 OFF_4 00CC R | 6 OFF_5 00DB R | 6 PAGER 0569 R - 6 PAGERB 03A6 R | PIO1CONT= 0083 | PPI1 = 0080 - 6 PRTMSG 0389 R | 6 PRTMSG1 0397 R | 6 PUNCH 016B R - RAMTARG_= D400 | RAMTARG_= F800 | 6 RDONLY 0226 R - RDR0 = 0048 | 6 READ 01DE R | 6 READER 016E R - 6 READ_HDP 02B6 R | 6 READ_HDP 02C5 R | 6 READ_HDP 02D4 R - 6 READ_HDP 02D4 R | 6 READ_HDP 02D5 R | 6 READ_RAM 022F R - 6 READ_ROM 025F R | RMAP = 0096 | ROMSTART= 0900 - ROMSTART= 0100 | 6 RPAGE 03B9 R | 6 SECPAGE 0398 R - 6 SECST 056D R | 6 SECTOR 0564 R | 6 SECTOR_B 057C R - 6 SECTOR_I 057B R | 6 SECTRN 01D5 R | 6 SELDSK 01AF R - 6 SETDMA 01D8 R | 6 SETSEC 01CF R | 6 SETTRK 01C9 R - 6 SPT_0 0092 R | 6 SPT_1 0083 R | 6 SPT_2 00A1 R - 6 SPT_3 00B0 R | 6 SPT_4 00BF R | 6 SPT_5 00CE R - STAT0 = 0044 | TDR0 = 0046 | 6 TMPBUF = 057C R - 6 TRACK 0562 R | 6 TTYIN 0179 R | 6 TTYISTS 0191 R - 6 TTYOSTS 019A R | 6 TTYOUT 0185 R | 6 TXT_RO_E 050F R - 6 TXT_STAR 0530 R | 6 V_SECTOR 056B R | 6 WBOOT 00F5 R - 6 WBOOTE 0003 R | 6 WRITE 0202 R | 6 WRITE_HD 031C R - 6 WRITE_HD 032B R | 6 WRITE_HD 033A R | 6 WRITE_HD 033A R - 6 WRITE_HD 033B R | 6 WRITE_RA 0286 R | 6 _cbioshc 0000 GR - 6 _cbioshc 0CF5 GR | 6 _cbioshc 0000 GR | 6 gerr2 044C R - 6 get_err 0442 R | ide_a0_l= 0001 | ide_a1_l= 0002 - ide_a2_l= 0004 | ide_asta= 0017 | ide_cmd_= 00EC - ide_cmd_= 0091 | ide_cmd_= 0020 | ide_cmd_= 0010 - ide_cmd_= 00E0 | ide_cmd_= 00E1 | ide_cmd_= 0030 - ide_comm= 000F | ide_cont= 0016 | ide_cs0_= 0008 - ide_cs1_= 0010 | ide_cyl_= 000C | ide_cyl_= 000D - ide_data= 0008 | ide_err = 0009 | 6 ide_hard 042F R - ide_head= 000E | ide_rd_l= 0040 | 6 ide_read 04CF R - ide_rst_= 0080 | ide_sec_= 000A | ide_sect= 000B - ide_stat= 000F | 6 ide_wait 0469 R | 6 ide_wait 044F R - 6 ide_wait 045B R | ide_wr_l= 0020 | 6 ide_writ 04EB R - rd_ide_8= 0092 | 6 rdblk2 0479 R | 6 read_dat 0477 R - 6 rst_dly 0439 R | 6 set_ppi_ 0505 R | 6 set_ppi_ 050A R - wr_ide_8= 0080 | 6 wr_lba 049F R | 6 wrblk2 048D R - 6 write_da 048B R - ASxxxx Assembler V02.00 + NoICE + SDCC mods + Flat24 (Zilog Z80 / Hitachi HD64180), page 2. - -Area Table - - 0 _CODE size 0 flags 0 - 1 _DATA size 0 flags 0 - 2 _OVERLAY size 0 flags 0 - 3 _HOME size 0 flags 0 - 4 _GSINIT size 0 flags 0 - 5 _GSFINAL size 0 flags 0 - 6 _CBIOS size CF5 flags 0 - 7 _CABS size 0 flags 0 diff --git a/doug/src/ccpb03.arf b/doug/src/ccpb03.arf deleted file mode 100755 index 66b472eb..00000000 --- a/doug/src/ccpb03.arf +++ /dev/null @@ -1,6 +0,0 @@ --mjx --i ccpb03.ihx --k /usr/local/share/sdcc/lib/z80 --l z80 -ccpb03.rel --e diff --git a/doug/src/ccpb03.lst b/doug/src/ccpb03.lst deleted file mode 100755 index 431ca66b..00000000 --- a/doug/src/ccpb03.lst +++ /dev/null @@ -1,1375 +0,0 @@ - 1 .title ccpb03.s derived from ccpb03.asm - 2 .sbttl by Douglas Goodall 5/16/2011 dwg - 3 - 4 .module ccpb03 - 5 .optsdcc -mz80 - 6 - 7 ;-------------------------------------------------------- - 8 ; Public variables in this module - 9 ;-------------------------------------------------------- - 10 .globl _ccp - 11 ;-------------------------------------------------------- - 12 ; special function registers - 13 ;-------------------------------------------------------- - 14 ;-------------------------------------------------------- - 15 ; ram data - 16 ;-------------------------------------------------------- - 17 .area _DATA - 18 ;-------------------------------------------------------- - 19 ; overlayable items in ram - 20 ;-------------------------------------------------------- - 21 .area _OVERLAY - 22 ;-------------------------------------------------------- - 23 ; external initialized ram data - 24 ;-------------------------------------------------------- - 25 ;-------------------------------------------------------- - 26 ; global & static initialisations - 27 ;-------------------------------------------------------- - 28 .area _HOME - 29 .area _GSINIT - 30 .area _GSFINAL - 31 .area _GSINIT - 32 ;-------------------------------------------------------- - 33 ; Home - 34 ;-------------------------------------------------------- - 35 .area _HOME - 36 .area _HOME - 37 ;-------------------------------------------------------- - 38 ; code - 39 ;-------------------------------------------------------- - 40 - 41 ; .area _CODE - 42 .area _CCPB03 - 43 - 0000 44 _ccp_start:: - 0000 45 _ccp: - 46 - 0001 47 MON = 1 ;ADD THE CCP MON COMMAND - 0001 48 USRDSP = 1 ;SHOW THE USER NUMBER - 0001 49 CHKU0B = 1 ;CHECK FOR TRANSIENTS ON USER 0 TOO - 0001 50 ENDFIL = 1 ;FILE FULL CCP SIZE - 51 ; - 52 ;************************************************************** - 53 ;* - 54 ;* C C P - C O N S O L E C O M M A N D P R O C E S S O R - 55 ;* - 56 ;************************************************************** - 57 ;* - 0003 58 IOBYTE = 3 ; I/O DEFINITION BYTE. - 0004 59 TDRIVE = 4 ; CURRENT DRIVE NAME AND USER NUMBER. - 0005 60 ENTRY = 5 ; ENTRY POINT FOR THE CP/M BDOS. - 005C 61 TFCB = 0x5C ; DEFAULT FILE CONTROL BLOCK. - 0080 62 TBUFF = 0x80 ; I/O BUFFER AND COMMAND LINE STORAGE. - 0100 63 TBASE = 0x0100 ; TRANSIANT PROGRAM STORAGE AREA. - FC00 64 MONADR = 0x0FC00 ;MONITOR PROGRAM - 65 ; - 66 ; SET CONTROL CHARACTER .EQUATES. - 67 ; - 0003 68 CNTRLC = 0x03 ; CONTROL-C - 0005 69 CNTRLE = 0x05 ; CONTROL-E - 0008 70 BS = 0x08 ; BACKSPACE - 0009 71 TAB = 0x09 ; TAB - 000A 72 LF = 0x0A ; LINE FEED - 000C 73 FF = 0x0C ; FORM FEED - 000D 74 CR = 0x0D ; CARRIAGE RETURN - 0010 75 CNTRLP = 0x10 ; CONTROL-P - 0012 76 CNTRLR = 0x12 ; CONTROL-R - 0013 77 CNTRLS = 0x13 ; CONTROL-S - 0015 78 CNTRLU = 0x15 ; CONTROL-U - 0018 79 CNTRLX = 0x18 ; CONTROL-X - 001A 80 CNTRLZ = 0x1A ; CONTROL-Z (END-OF-FILE MARK) - 002A 81 ASTERICK = 0x2A - 003A 82 COLON = 0x3A - 003C 83 LESSTHAN = 0x3C - 0020 84 ASCSPACE = 0x20 ; SPACE - 002E 85 PERIOD = 0x2e ; PERIOD - 003D 86 EQUAL = 0x3D - 003E 87 GREATERTHAN = 0x3E - 003F 88 QUESTION = 0x3F ;QUESTION MARK - 005F 89 UNDERSCORE = 0x5F - 007B 90 LCURLY = 0x7B ; { - 007F 91 DEL = 0x7F ; RUBOUT - 92 ; - 93 ; SET ORIGIN FOR CP/M - 94 ; - 95 - 003B 96 NK = 59 ;SYSTEM SIZE - 9C00 97 BASE = (NK*1024)-0x5000 - D000 98 CCPO = BASE+0x3400 ;CCP ORIGIN - D800 99 BDOSO = BASE+0x3C00 ;BDOS ORIGIN - E600 100 BIOSO = BASE+0x4A00 ;BIOS ORIGIN - 101 - 102 ;dwg; .ORG CCPO - 103 ; - 0000 C3r54s03 104 CBASE: JP COMMAND ; EXECUTE COMMAND PROCESSOR (CCP). - 0003 C3r50s03 105 JP CLEARBUF ; ENTRY TO EMPTY INPUT BUFFER BEFORE STARTING CCP. - 106 - 107 ; - 108 ; STANDARD CP/M CCP INPUT BUFFER. FORMAT IS (MAX LENGTH), - 109 ; (ACTUAL LENGTH), (CHAR #1), (CHAR #2), (CHAR #3), ETC. - 110 ; - 0006 7F 111 INBUFF: .DB 127 ; LENGTH OF INPUT BUFFER. - 112 - 113 ; N8VEM - if add any text after this point, change .DB 0 below to length - 114 ; and put a 0 after the text, and delete the same number of zeros after the dig - 115 ; so that inpoint ends up at the same spot - 116 ; INBUFF+1 is cleared on the next warm boot, so only runs once. - 0007 00 117 .DB 0 ;CURRENT LENGTH OF CONTENTS. - 118 - 119 - 120 ; .DB 17 ; Autoboot length of string - 121 ; .DB "SUPERSUB AUTOEXEC" - 122 ; .DB 0 ; zero at end - 123 - 124 - 0008 43 4F 50 59 52 49 125 .ascii "COPYRIGHT" - 47 48 54 - 0011 20 31 39 37 39 20 126 .ascii " 1979 (C) BY " - 28 43 29 20 42 59 - 20 - 001E 44 49 47 49 54 41 127 .ascii "DIGITAL RESEARCH " - 4C 20 52 45 53 45 - 41 52 43 48 20 20 - 20 20 - 0032 20 20 128 .ascii " " - 129 - 130 ;dwg; .ORG INBUFF+128 - 131 ;dwg; becausje org's are not allowed in rel areas, it has been - 132 ; replaced with the following array of .db's to achieve the - 133 ; same purpose - 0034 00 00 00 00 00 00 134 .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - 00 00 00 00 00 00 - 00 00 00 00 - 0044 00 00 00 00 00 00 135 .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - 00 00 00 00 00 00 - 00 00 00 00 - 0054 00 00 00 00 00 00 136 .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - 00 00 00 00 00 00 - 00 00 00 00 - 0064 00 00 00 00 00 00 137 .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - 00 00 00 00 00 00 - 00 00 00 00 - 0074 00 00 00 00 00 00 138 .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - 00 00 00 00 00 00 - 00 00 00 00 - 0084 00 00 139 .db 0,0 - 140 - 141 ;; s/b d086 here - 142 - 0086r08s00 143 INPOINT:.DW INBUFF+2 ; INPUT LINE POINTER - 0088 00 00 144 NAMEPNT:.DW 0 ; INPUT LINE POINTER USED FOR ERROR MESSAGE. POINTS TO - 145 ; ;START OF NAME IN ERROR. - 146 ; - 147 ; ROUTINE TO PRINT (A) ON THE CONSOLE. ALL REGISTERS USED. - 148 ; - 008A 5F 149 PRINT: LD E,A ; SETUP BDOS CALL. - 008B 0E 02 150 LD C,#2 - 008D C3 05 00 151 JP ENTRY - 152 ; - 153 ; ROUTINE TO PRINT (A) ON THE CONSOLE AND TO SAVE (BC). - 154 ; - 0090 C5 155 PRINTB: PUSH BC - 0091 CDr8As00 156 CALL PRINT - 0094 C1 157 POP BC - 0095 C9 158 RET - 159 ; - 160 ; ROUTINE TO SEND A CARRIAGE RETURN, LINE FEED COMBINATION - 161 ; TO THE CONSOLE. - 162 ; - 0096 3E 0D 163 CRLF: LD A,#CR - 0098 CDr90s00 164 CALL PRINTB - 009B 3E 0A 165 LD A,#LF - 009D C3r90s00 166 JP PRINTB - 167 ; - 168 ; ROUTINE TO SEND ONE SPACE TO THE CONSOLE AND SAVE (BC). - 169 ; - 00A0 3E 20 170 SPACE: LD A,#ASCSPACE - 00A2 C3r90s00 171 JP PRINTB - 172 ; - 173 ; ROUTINE TO PRINT CHARACTER STRING POINTED TO BE (BC) ON THE - 174 ; CONSOLE. IT MUST TERMINATE WITH A NULL BYTE. - 175 ; - 00A5 C5 176 PLINE: PUSH BC - 00A6 CDr96s00 177 CALL #CRLF - 00A9 E1 178 POP HL - 00AA 7E 179 PLINE2: LD A,(HL) - 00AB B7 180 OR A - 00AC C8 181 RET Z - 00AD 23 182 INC HL - 00AE E5 183 PUSH HL - 00AF CDr8As00 184 CALL PRINT - 00B2 E1 185 POP HL - 00B3 C3rAAs00 186 JP PLINE2 - 187 ; - 188 ; ROUTINE TO RESET THE DISK SYSTEM. - 189 ; - 00B6 0E 0D 190 RESDSK: LD C,#13 - 00B8 C3 05 00 191 JP ENTRY - 192 ; - 193 ; ROUTINE TO SELECT DISK (A). - 194 ; - 00BB 5F 195 DSKSEL: LD E,A - 00BC 0E 0E 196 LD C,#14 - 00BE C3 05 00 197 JP ENTRY - 198 ; - 199 ; ROUTINE TO CALL BDOS AND SAVE THE RETURN CODE. THE ZERO - 200 ; FLAG IS SET ON A RETURN OF 0FFH. - 201 ; - 00C1 CD 05 00 202 ENTRY1: CALL ENTRY - 00C4 32rFAs07 203 LD (RTNCODE),A ; SAVE RETURN CODE. - 00C7 3C 204 INC A ; SET ZERO IF 0FFH RETURNED. - 00C8 C9 205 RET - 206 ; - 207 ; ROUTINE TO OPEN A FILE. (DE) MUST POINT TO THE FCB. - 208 ; - 00C9 0E 0F 209 OPEN: LD C,#15 - 00CB C3rC1s00 210 JP ENTRY1 - 211 ; - 212 ; ROUTINE TO OPEN FILE AT (FCB). - 213 ; - 00CE AF 214 OPENFCB:XOR A ; CLEAR THE RECORD NUMBER BYTE AT FCB+32 - 00CF 32rF9s07 215 LD (FCB+32),A - 00D2 11rD9s07 216 LD DE,#FCB - 00D5 C3rC9s00 217 JP OPEN - 218 ; - 219 ; ROUTINE TO CLOSE A FILE. (DE) POINTS TO FCB. - 220 ; - 00D8 0E 10 221 CLOSE: LD C,#16 - 00DA C3rC1s00 222 JP ENTRY1 - 223 ; - 224 ; ROUTINE TO SEARCH FOR THE FIRST FILE WITH AMBIGUEOUS NAME - 225 ; (DE). - 226 ; - 00DD 0E 11 227 SRCHFST:LD C,#17 - 00DF C3rC1s00 228 JP ENTRY1 - 229 ; - 230 ; SEARCH FOR THE NEXT AMBIGEOUS FILE NAME. - 231 ; - 00E2 0E 12 232 SRCHNXT:LD C,#18 - 00E4 C3rC1s00 233 JP ENTRY1 - 234 ; - 235 ; SEARCH FOR FILE AT (FCB). - 236 ; - 00E7 11rD9s07 237 SRCHFCB:LD DE,#FCB - 00EA C3rDDs00 238 JP SRCHFST - 239 ; - 240 ; ROUTINE TO DELETE A FILE POINTED TO BY (DE). - 241 ; - 00ED 0E 13 242 DELETE: LD C,#19 - 00EF C3 05 00 243 JP ENTRY - 244 ; - 245 ; ROUTINE TO CALL THE BDOS AND SET THE ZERO FLAG IF A ZERO - 246 ; STATUS IS RETURNED. - 247 ; - 00F2 CD 05 00 248 ENTRY2: CALL ENTRY - 00F5 B7 249 OR A ; SET ZERO FLAG IF APPROPRIATE. - 00F6 C9 250 RET - 251 ; - 252 ; ROUTINE TO READ THE NEXT RECORD FROM A S.EQUENTIAL FILE. - 253 ; (DE) POINTS TO THE FCB. - 254 ; - 00F7 0E 14 255 RDREC: LD C,#20 - 00F9 C3rF2s00 256 JP ENTRY2 - 257 ; - 258 ; ROUTINE TO READ FILE AT (FCB). - 259 ; - 00FC 11rD9s07 260 READFCB:LD DE,#FCB - 00FF C3rF7s00 261 JP RDREC - 262 ; - 263 ; ROUTINE TO WRITE THE NEXT RECORD OF A S.EQUENTIAL FILE. - 264 ; (DE) POINTS TO THE FCB. - 265 ; - 0102 0E 15 266 WRTREC: LD C,#21 - 0104 C3rF2s00 267 JP ENTRY2 - 268 ; - 269 ; ROUTINE TO CREATE THE FILE POINTED TO BY (DE). - 270 ; - 0107 0E 16 271 CREATE: LD C,#22 - 0109 C3rC1s00 272 JP ENTRY1 - 273 ; - 274 ; ROUTINE TO RENAME THE FILE POINTED TO BY (DE). NOTE THAT - 275 ; THE NEW NAME STARTS AT (DE+16). - 276 ; - 010C 0E 17 277 RENAM: LD C,#23 - 010E C3 05 00 278 JP ENTRY - 279 ; - 280 ; GET THE CURRENT USER CODE. - 281 ; - 0111 1E FF 282 GETUSR: LD E,#0x0FF - 283 ; - 284 ; ROUTNE TO GET OR SET THE CURRENT USER CODE. - 285 ; IF (E) IS FF THEN THIS IS A GET, ELSE IT IS A SET. - 286 ; - 0113 287 GETSETUC: - 0113 0E 20 288 LD C,#32 - 0115 C3 05 00 289 JP ENTRY - 290 ; - 291 ; ROUTINE TO SET THE CURRENT DRIVE BYTE AT (TDRIVE). - 292 ; - 0118 CDr11s01 293 SETCDRV:CALL GETUSR ; GET USER NUMBER - 011B 87 294 ADD A,A ; AND SHIFT INTO THE UPPER 4 BITS. - 011C 87 295 ADD A,A - 011D 87 296 ADD A,A - 011E 87 297 ADD A,A - 011F 21rFBs07 298 LD HL,#CDRIVE ; NOW ADD IN THE CURRENT DRIVE NUMBER. - 0122 B6 299 OR (HL) - 0123 32 04 00 300 LD (TDRIVE),A ; AND SAVE. - 0126 C9 301 RET - 302 ; - 303 ; MOVE CURRENTLY ACTIVE DRIVE DOWN TO (TDRIVE). - 304 ; - 0127 3ArFBs07 305 MOVECD: LD A,(CDRIVE) - 012A 32 04 00 306 LD (TDRIVE),A - 012D C9 307 RET - 308 ; - 309 ; ROUTINE TO CONVERT (A) INTO UPPER CASE ASCII. ONLY LETTERS - 310 ; ARE AFFECTED. - 311 ; - 012E FE 41 312 UPPER: CP #0x41 ; CHECK FOR LETTERS IN THE RANGE OF 'A' TO 'Z'. - 0130 D8 313 RET C - 0131 FE 7B 314 CP #LCURLY - 0133 D0 315 RET NC - 0134 E6 5F 316 AND #0x5F ; CONVERT IT IF FOUND. - 0136 C9 317 RET - 318 ; - 319 ; ROUTINE TO GET A LINE OF INPUT. WE MUST CHECK TO SEE IF THE - 320 ; USER IS IN (BATCH) MODE. IF SO, THEN READ THE INPUT FROM FILE - 321 ; ($$$.SUB). AT THE END, RESET TO CONSOLE INPUT. - 322 ; - 0137 3ArB7s07 323 GETINP: LD A,(BATCH) ; IF =0, THEN USE CONSOLE INPUT. - 013A B7 324 OR A - 013B CAr94s01 325 JP Z,GETINP1 - 326 ; - 327 ; USE THE SUBMIT FILE ($$$.SUB) WHICH IS PREPARED BY A - 328 ; SUBMIT RUN. IT MUST BE ON DRIVE (A) AND IT WILL BE DELETED - 329 ; IF AND ERROR OCCURES (LIKE EOF). - 330 ; - 013E 3ArFBs07 331 LD A,(CDRIVE) ; SELECT DRIVE 0 IF NEED BE. - 0141 B7 332 OR A - 0142 3E 00 333 LD A,#0 ; ALWAYS USE DRIVE A FOR SUBMIT. - 0144 C4rBBs00 334 CALL NZ,DSKSEL ; SELECT IT IF R.EQUIRED. - 0147 11rB8s07 335 LD DE,#BATCHFCB - 014A CDrC9s00 336 CALL OPEN ; LOOK FOR IT. - 014D CAr94s01 337 JP Z,GETINP1 ; IF NOT THERE, USE NORMAL INPUT. - 0150 3ArC7s07 338 LD A,(BATCHFCB+15) ; GET LAST RECORD NUMBER+1. - 0153 3D 339 DEC A - 0154 32rD8s07 340 LD (BATCHFCB+32),A - 0157 11rB8s07 341 LD DE,#BATCHFCB - 015A CDrF7s00 342 CALL RDREC ; READ LAST RECORD. - 015D C2r94s01 343 JP NZ,GETINP1 ; QUIT ON END OF FILE. - 344 ; - 345 ; MOVE THIS RECORD INTO INPUT BUFFER. - 346 ; - 0160 11r07s00 347 LD DE,#INBUFF+1 - 0163 21 80 00 348 LD HL,#TBUFF ; DATA WAS READ INTO BUFFER HERE. - 0166 06 80 349 LD B,#128 ; ALL 128 CHARACTERS MAY BE USED. - 0168 CDr38s04 350 CALL HL2DE ; (HL) TO (DE), (B) BYTES. - 016B 21rC6s07 351 LD HL,#BATCHFCB+14 - 016E 36 00 352 LD (HL),#0 ; ZERO OUT THE 'S2' BYTE. - 0170 23 353 INC HL ; AND DECREMENT THE RECORD COUNT. - 0171 35 354 DEC (HL) - 0172 11rB8s07 355 LD DE,#BATCHFCB ; CLOSE THE BATCH FILE NOW. - 0175 CDrD8s00 356 CALL CLOSE - 0178 CAr94s01 357 JP Z,GETINP1 ; QUIT ON AN ERROR. - 017B 3ArFBs07 358 LD A,(CDRIVE) ; RE-SELECT PREVIOUS DRIVE IF NEED BE. - 017E B7 359 OR A - 017F C4rBBs00 360 CALL NZ,DSKSEL ; DON'T DO NEEDLESS SELECTS. - 361 ; - 362 ; PRINT LINE JUST READ ON CONSOLE. - 363 ; - 0182 21r08s00 364 LD HL,#INBUFF+2 - 0185 CDrAAs00 365 CALL PLINE2 - 0188 CDrC0s01 366 CALL CHKCON ; CHECK CONSOLE, QUIT ON A KEY. - 018B CArA5s01 367 JP Z,GETINP2 ; JUMP IF NO KEY IS PRESSED. - 368 ; - 369 ; TERMINATE THE SUBMIT JOB ON ANY KEYBOARD INPUT. DELETE THIS - 370 ; FILE SUCH THAT IT IS NOT RE-STARTED AND JUMP TO NORMAL KEYBOARD - 371 ; INPUT SECTION. - 372 ; - 018E CDrDBs01 373 CALL DELBATCH ; DELETE THE BATCH FILE. - 0191 C3r7As03 374 JP CMMND1 ; AND RESTART COMMAND INPUT. - 375 ; - 376 ; GET HERE FOR NORMAL KEYBOARD INPUT. DELETE THE SUBMIT FILE - 377 ; INCASE THERE WAS ONE. - 378 ; - 0194 CDrDBs01 379 GETINP1:CALL DELBATCH ; DELETE FILE ($$$.SUB). - 0197 CDr18s01 380 CALL SETCDRV ; RESET ACTIVE DISK. - 019A 0E 0A 381 LD C,#10 ; GET LINE FROM CONSOLE DEVICE. - 019C 11r06s00 382 LD DE,#INBUFF - 019F CD 05 00 383 CALL ENTRY - 01A2 CDr27s01 384 CALL MOVECD ; RESET CURRENT DRIVE (AGAIN). - 385 ; - 386 ; CONVERT INPUT LINE TO UPPER CASE. - 387 ; - 01A5 21r07s00 388 GETINP2:LD HL,#INBUFF+1 - 01A8 46 389 LD B,(HL) ; (B)=CHARACTER COUNTER. - 01A9 23 390 GETINP3:INC HL - 01AA 78 391 LD A,B ; END OF THE LINE? - 01AB B7 392 OR A - 01AC CArB8s01 393 JP Z,GETINP4 - 01AF 7E 394 LD A,(HL) ; CONVERT TO UPPER CASE. - 01B0 CDr2Es01 395 CALL UPPER - 01B3 77 396 LD (HL),A - 01B4 05 397 DEC B ; ADJUST CHARACTER COUNT. - 01B5 C3rA9s01 398 JP GETINP3 - 01B8 77 399 GETINP4:LD (HL),A ; ADD TRAILING NULL. - 01B9 21r08s00 400 LD HL,#INBUFF+2 - 01BC 22r86s00 401 LD (INPOINT),HL ; RESET INPUT LINE POINTER. - 01BF C9 402 RET - 403 ; - 404 ; ROUTINE TO CHECK THE CONSOLE FOR A KEY PRESSED. THE ZERO - 405 ; FLAG IS SET IS NONE, ELSE THE CHARACTER IS RETURNED IN (A). - 406 ; - 01C0 0E 0B 407 CHKCON: LD C,#11 ; CHECK CONSOLE. - 01C2 CD 05 00 408 CALL ENTRY - 01C5 B7 409 OR A - 01C6 C8 410 RET Z ; RETURN IF NOTHING. - 01C7 0E 01 411 LD C,#1 ; ELSE GET CHARACTER. - 01C9 CD 05 00 412 CALL ENTRY - 01CC B7 413 OR A ; CLEAR ZERO FLAG AND RETURN. - 01CD C9 414 RET - 415 ; - 416 ; ROUTINE TO GET THE CURRENTLY ACTIVE DRIVE NUMBER. - 417 ; - 01CE 0E 19 418 GETDSK: LD C,#25 - 01D0 C3 05 00 419 JP ENTRY - 420 ; - 421 ; SET THE STABDARD DMA ADDRESS. - 422 ; - 01D3 11 80 00 423 STDDMA: LD DE,#TBUFF - 424 ; - 425 ; ROUTINE TO SET THE DMA ADDRESS TO (DE). - 426 ; - 01D6 0E 1A 427 DMASET: LD C,#26 - 01D8 C3 05 00 428 JP ENTRY - 429 ; - 430 ; DELETE THE BATCH FILE CREATED BY SUBMIT. - 431 ; - 01DB 432 DELBATCH: - 01DB 21rB7s07 433 LD HL,#BATCH ; IS BATCH ACTIVE? - 01DE 7E 434 LD A,(HL) - 01DF B7 435 OR A - 01E0 C8 436 RET Z - 01E1 36 00 437 LD (HL),#0 ; YES, DE-ACTIVATE IT. - 01E3 AF 438 XOR A - 01E4 CDrBBs00 439 CALL DSKSEL ; SELECT DRIVE 0 FOR SURE. - 01E7 11rB8s07 440 LD DE,#BATCHFCB ; AND DELETE THIS FILE. - 01EA CDrEDs00 441 CALL DELETE - 01ED 3ArFBs07 442 LD A,(CDRIVE) ; RESET CURRENT DRIVE. - 01F0 C3rBBs00 443 JP DSKSEL - 444 ; - 445 ; PRINT BACK FILE NAME WITH A '?' TO INDICATE A SYNTAX ERROR. - 446 ; - 01F3 CDr96s00 447 SYNERR: CALL CRLF ; END CURRENT LINE. - 01F6 2Ar88s00 448 LD HL,(NAMEPNT) ; THIS POINTS TO NAME IN ERROR. - 01F9 7E 449 SYNERR1:LD A,(HL) ; PRINT IT UNTIL A SPACE OR NULL IS FOUND. - 01FA FE 20 450 CP #ASCSPACE - 01FC CAr0Cs02 451 JP Z,SYNERR2 - 01FF B7 452 OR A - 0200 CAr0Cs02 453 JP Z,SYNERR2 - 0203 E5 454 PUSH HL - 0204 CDr8As00 455 CALL PRINT - 0207 E1 456 POP HL - 0208 23 457 INC HL - 0209 C3rF9s01 458 JP SYNERR1 - 020C 3E 3F 459 SYNERR2:LD A,#QUESTION ; ADD TRAILING '?'. - 020E CDr8As00 460 CALL PRINT - 0211 CDr96s00 461 CALL CRLF - 0214 CDrDBs01 462 CALL DELBATCH ; DELETE ANY BATCH FILE. - 0217 C3r7As03 463 JP CMMND1 ; AND RESTART FROM CONSOLE INPUT. - 464 ; - 465 ; CHECK CHARACTER AT (DE) FOR LEGAL COMMAND INPUT. NOTE THAT THE - 466 ; ZERO FLAG IS SET IF THE CHARACTER IS A DELIMITER. - 467 ; - 021A 1A 468 CHECK: LD A,(DE) - 021B B7 469 OR A - 021C C8 470 RET Z - 021D FE 20 471 CP #ASCSPACE ; CONTROL CHARACTERS ARE NOT LEGAL HERE. - 021F DArF3s01 472 JP C,SYNERR - 0222 C8 473 RET Z ; CHECK FOR VALID DELIMITER. - 0223 FE 3D 474 CP #EQUAL - 0225 C8 475 RET Z - 0226 FE 5F 476 CP #UNDERSCORE - 0228 C8 477 RET Z - 0229 FE 2E 478 CP #PERIOD - 022B C8 479 RET Z - 022C FE 3A 480 CP #COLON - 022E C8 481 RET Z - 022F FE 3B 482 CP #0x3b - 0231 C8 483 RET Z - 0232 FE 3C 484 CP #LESSTHAN - 0234 C8 485 RET Z - 0235 FE 3E 486 CP #GREATERTHAN - 0237 C8 487 RET Z - 0238 C9 488 RET - 489 ; - 490 ; GET THE NEXT NON-BLANK CHARACTER FROM (DE). - 491 ; - 0239 492 NONBLANK: - 0239 1A 493 LD A,(DE) - 023A B7 494 OR A ; STRING ENDS WITH A NULL. - 023B C8 495 RET Z - 023C FE 20 496 CP #ASCSPACE - 023E C0 497 RET NZ - 023F 13 498 INC DE - 0240 C3r39s02 499 JP NONBLANK - 500 ; - 501 ; ADD (HL)=(HL)+(A) - 502 ; - 0243 85 503 ADDHL: ADD A,L - 0244 6F 504 LD L,A - 0245 D0 505 RET NC ; TAKE CARE OF ANY CARRY. - 0246 24 506 INC H - 0247 C9 507 RET - 508 ; - 509 ; CONVERT THE FIRST NAME IN (FCB). - 510 ; - 0248 3E 00 511 CONVFST:LD A,#0 - 512 ; - 513 ; FORMAT A FILE NAME (CONVERT * TO '?', ETC.). ON RETURN, - 514 ; (A)=0 IS AN UNAMBIGEOUS NAME WAS SPECIFIED. ENTER WITH (A) .EQUAL TO - 515 ; THE POSITION WITHIN THE FCB FOR THE NAME (EITHER 0 OR 16). - 516 ; - 024A 21rD9s07 517 CONVERT:LD HL,#FCB - 024D CDr43s02 518 CALL ADDHL - 0250 E5 519 PUSH HL - 0251 E5 520 PUSH HL - 0252 AF 521 XOR A - 0253 32rFCs07 522 LD (CHGDRV),A ; INITIALIZE DRIVE CHANGE FLAG. - 0256 2Ar86s00 523 LD HL,(INPOINT) ; SET (HL) AS POINTER INTO INPUT LINE. - 0259 EB 524 EX DE,HL - 025A CDr39s02 525 CALL NONBLANK ; GET NEXT NON-BLANK CHARACTER. - 025D EB 526 EX DE,HL - 025E 22r88s00 527 LD (NAMEPNT),HL ; SAVE POINTER HERE FOR ANY ERROR MESSAGE. - 0261 EB 528 EX DE,HL - 0262 E1 529 POP HL - 0263 1A 530 LD A,(DE) ; GET FIRST CHARACTER. - 0264 B7 531 OR A - 0265 CAr73s02 532 JP Z,CONVRT1 - 0268 DE 40 533 SBC A,#0x41-1 ; MIGHT BE A DRIVE NAME, CONVERT TO BINARY. - 026A 47 534 LD B,A ; AND SAVE. - 026B 13 535 INC DE ; CHECK NEXT CHARACTER FOR A ':'. - 026C 1A 536 LD A,(DE) - 026D FE 3A 537 CP #COLON - 026F CAr7As02 538 JP Z,CONVRT2 - 0272 1B 539 DEC DE ; NOPE, MOVE POINTER BACK TO THE START OF THE LINE. - 0273 3ArFBs07 540 CONVRT1:LD A,(CDRIVE) - 0276 77 541 LD (HL),A - 0277 C3r80s02 542 JP CONVRT3 - 027A 78 543 CONVRT2:LD A,B - 027B 32rFCs07 544 LD (CHGDRV),A ; SET CHANGE IN DRIVES FLAG. - 027E 70 545 LD (HL),B - 027F 13 546 INC DE - 547 ; - 548 ; CONVERT THE BASIC FILE NAME. - 549 ; - 0280 06 08 550 CONVRT3:LD B,#8 - 0282 CDr1As02 551 CONVRT4:CALL CHECK - 0285 CArA3s02 552 JP Z,CONVRT8 - 0288 23 553 INC HL - 0289 FE 2A 554 CP #ASTERICK ; NOTE THAT AN '*' WILL FILL THE REMAINING - 028B C2r93s02 555 JP NZ,CONVRT5 ; FIELD WITH '?'. - 028E 36 3F 556 LD (HL),#QUESTION - 0290 C3r95s02 557 JP CONVRT6 - 0293 77 558 CONVRT5:LD (HL),A - 0294 13 559 INC DE - 0295 05 560 CONVRT6:DEC B - 0296 C2r82s02 561 JP NZ,CONVRT4 - 0299 CDr1As02 562 CONVRT7:CALL CHECK ; GET NEXT DELIMITER. - 029C CArAAs02 563 JP Z,GETEXT - 029F 13 564 INC DE - 02A0 C3r99s02 565 JP CONVRT7 - 02A3 23 566 CONVRT8:INC HL ; BLANK FILL THE FILE NAME. - 02A4 36 20 567 LD (HL),#ASCSPACE - 02A6 05 568 DEC B - 02A7 C2rA3s02 569 JP NZ,CONVRT8 - 570 ; - 571 ; GET THE EXTENSION AND CONVERT IT. - 572 ; - 02AA 06 03 573 GETEXT: LD B,#3 - 02AC FE 2E 574 CP #PERIOD - 02AE C2rD3s02 575 JP NZ,GETEXT5 - 02B1 13 576 INC DE - 02B2 CDr1As02 577 GETEXT1:CALL CHECK - 02B5 CArD3s02 578 JP Z,GETEXT5 - 02B8 23 579 INC HL - 02B9 FE 2A 580 CP #ASTERICK - 02BB C2rC3s02 581 JP NZ,GETEXT2 - 02BE 36 3F 582 LD (HL),#QUESTION - 02C0 C3rC5s02 583 JP GETEXT3 - 02C3 77 584 GETEXT2:LD (HL),A - 02C4 13 585 INC DE - 02C5 05 586 GETEXT3:DEC B - 02C6 C2rB2s02 587 JP NZ,GETEXT1 - 02C9 CDr1As02 588 GETEXT4:CALL CHECK - 02CC CArDAs02 589 JP Z,GETEXT6 - 02CF 13 590 INC DE - 02D0 C3rC9s02 591 JP GETEXT4 - 02D3 23 592 GETEXT5:INC HL - 02D4 36 20 593 LD (HL),#ASCSPACE - 02D6 05 594 DEC B - 02D7 C2rD3s02 595 JP NZ,GETEXT5 - 02DA 06 03 596 GETEXT6:LD B,#3 - 02DC 23 597 GETEXT7:INC HL - 02DD 36 00 598 LD (HL),#0 - 02DF 05 599 DEC B - 02E0 C2rDCs02 600 JP NZ,GETEXT7 - 02E3 EB 601 EX DE,HL - 02E4 22r86s00 602 LD (INPOINT),HL ; SAVE INPUT LINE POINTER. - 02E7 E1 603 POP HL - 604 ; - 605 ; CHECK TO SEE IF THIS IS AN AMBIGEOUS FILE NAME SPECIFICATION. - 606 ; SET THE (A) REGISTER TO NON ZERO IF IT IS. - 607 ; - 02E8 01 0B 00 608 LD BC,#11 ; SET NAME LENGTH. - 02EB 23 609 GETEXT8:INC HL - 02EC 7E 610 LD A,(HL) - 02ED FE 3F 611 CP #QUESTION ; ANY QUESTION MARKS? - 02EF C2rF3s02 612 JP NZ,GETEXT9 - 02F2 04 613 INC B ; COUNT THEM. - 02F3 0D 614 GETEXT9:DEC C - 02F4 C2rEBs02 615 JP NZ,GETEXT8 - 02F7 78 616 LD A,B - 02F8 B7 617 OR A - 02F9 C9 618 RET - 619 ; - 620 ; CP/M COMMAND TABLE. NOTE COMMANDS CAN BE EITHER 3 OR 4 CHARACTERS LONG. - 621 ; - 0001 622 .if MON - 0007 623 NUMCMDS = 7 ; NUMBER OF COMMANDS - 624 .else - 625 NUMCMDS = 6 ; NUMBER OF COMMANDS - 626 .endif - 627 - 02FA 44 49 52 20 628 CMDTBL: .ascii "DIR " - 02FE 45 52 41 20 629 .ascii "ERA " - 0302 54 59 50 45 630 .ascii "TYPE" - 0306 53 41 56 45 631 .ascii "SAVE" - 030A 52 45 4E 20 632 .ascii "REN " - 030E 55 53 45 52 633 .ascii "USER" - 0001 634 .if MON - 0312 4D 4F 4E 20 635 .ascii "MON " - 636 .ENDIF - 637 - 0316r70s04 638 CMDADR: .DW DIRECT - 0318r18s05 639 .DW ERASE - 031Ar56s05 640 .DW TYPE - 031CrA6s05 641 .DW SAVE - 031Er09s06 642 .DW RENAME - 0320r87s06 643 .DW USER - 0001 644 .IF MON - 0322r6Ds04 645 .DW MONITOR - 646 .ENDIF - 0324r9Es06 647 .DW UNKNOWN - 648 ; - 649 ; SEARCH THE COMMAND TABLE FOR A MATCH WITH WHAT HAS JUST - 650 ; BEEN ENTERED. IF A MATCH IS FOUND, THEN WE JUMP TO THE - 651 ; PROPER SECTION. ELSE JUMP TO (UNKNOWN). - 652 ; ON RETURN, THE (C) REGISTER IS SET TO THE COMMAND NUMBER - 653 ; THAT MATCHED (OR NUMCMDS+1 IF NO MATCH). - 654 ; - 0326 21rFAs02 655 SEARCH: LD HL,#CMDTBL - 0329 0E 00 656 LD C,#0 - 032B 79 657 SEARCH1:LD A,C - 032C FE 07 658 CP #NUMCMDS ; THIS COMMANDS EXISTS. - 032E D0 659 RET NC - 032F 11rDAs07 660 LD DE,#FCB+1 ; CHECK THIS ONE. - 0332 06 04 661 LD B,#4 ; MAX COMMAND LENGTH. - 0334 1A 662 SEARCH2:LD A,(DE) - 0335 BE 663 CP (HL) - 0336 C2r47s03 664 JP NZ,SEARCH3 ; NOT A MATCH. - 0339 13 665 INC DE - 033A 23 666 INC HL - 033B 05 667 DEC B - 033C C2r34s03 668 JP NZ,SEARCH2 - 033F 1A 669 LD A,(DE) ; ALLOW A 3 CHARACTER COMMAND TO MATCH. - 0340 FE 20 670 CP #ASCSPACE - 0342 C2r4Cs03 671 JP NZ,SEARCH4 - 0345 79 672 LD A,C ; SET RETURN REGISTER FOR THIS COMMAND. - 0346 C9 673 RET - 0347 23 674 SEARCH3:INC HL - 0348 05 675 DEC B - 0349 C2r47s03 676 JP NZ,SEARCH3 - 034C 0C 677 SEARCH4:INC C - 034D C3r2Bs03 678 JP SEARCH1 - 679 ; - 680 ; SET THE INPUT BUFFER TO EMPTY AND THEN START THE COMMAND - 681 ; PROCESSOR (CCP). - 682 ; - 0350 683 CLEARBUF: - 0350 AF 684 XOR A - 0351 32r07s00 685 LD (INBUFF+1),A ; SECOND BYTE IS ACTUAL LENGTH. - 0354 31rB7s07 686 COMMAND:LD SP,#CCPSTACK ; SETUP STACK AREA. - 0357 C5 687 PUSH BC ; NOTE THAT (C) SHOULD BE .EQUAL TO: - 0358 79 688 LD A,C ; (UUUUDDDD) WHERE 'UUUU' IS THE USER NUMBER - 0359 1F 689 RRA ; AND 'DDDD' IS THE DRIVE NUMBER. - 035A 1F 690 RRA - 035B 1F 691 RRA - 035C 1F 692 RRA - 035D E6 0F 693 AND #0x0F ; ISOLATE THE USER NUMBER. - 035F 5F 694 LD E,A - 0360 CDr13s01 695 CALL GETSETUC ; AND SET IT. - 0363 CDrB6s00 696 CALL RESDSK ; RESET THE DISK SYSTEM. - 0366 32rB7s07 697 LD (BATCH),A ; CLEAR BATCH MODE FLAG. - 0369 C1 698 POP BC - 036A 79 699 LD A,C - 036B E6 0F 700 AND #0x0F ; ISOLATE THE DRIVE NUMBER. - 036D 32rFBs07 701 LD (CDRIVE),A ; AND SAVE. - 0370 CDrBBs00 702 CALL DSKSEL ; ...AND SELECT. - 0373 3Ar07s00 703 LD A,(INBUFF+1) - 0376 B7 704 OR A ; ANYTHING IN INPUT BUFFER ALREADY? - 0377 C2rA6s03 705 JP NZ,CMMND2 ; YES, WE JUST PROCESS IT. - 706 ; - 707 ; ENTRY POINT TO GET A COMMAND LINE FROM THE CONSOLE. - 708 ; - 037A 31rB7s07 709 CMMND1: LD SP,#CCPSTACK ; SET STACK STRAIGHT. - 037D CDr96s00 710 CALL CRLF ; START A NEW LINE ON THE SCREEN. - 0380 CDrCEs01 711 CALL GETDSK ; GET CURRENT DRIVE. - 0383 C6 41 712 ADD A,#0x41 - 0385 CDr8As00 713 CALL PRINT ; PRINT CURRENT DRIVE. - 0001 714 .IF USRDSP - 0388 CDr11s01 715 CALL GETUSR ;GET CURRENT USER NUMBER - 038B FE 0A 716 CP #10 ;TWO DIGITS? - 038D 38 0A 717 JR C,CMMND3 ;NO - 038F 3E 31 718 LD A,#0x31 ;PRINT LEADING '1' - 0391 CDr8As00 719 CALL PRINT - 0394 CDr11s01 720 CALL GETUSR ;GET CURRENT USER NUMBER - 0397 D6 0A 721 SUB #10 ;SUBTRACT 10 - 0399 C6 30 722 CMMND3: ADD A,#0x30 - 039B CDr8As00 723 CALL PRINT - 724 .ENDIF - 039E 3E 3E 725 LD A,#GREATERTHAN - 03A0 CDr8As00 726 CALL PRINT ; AND ADD PROMPT. - 03A3 CDr37s01 727 CALL GETINP ; GET LINE FROM USER. - 728 ; - 729 ; PROCESS COMMAND LINE HERE. - 730 ; - 03A6 11 80 00 731 CMMND2: LD DE,#TBUFF - 03A9 CDrD6s01 732 CALL DMASET ; SET STANDARD DMA ADDRESS. - 03AC CDrCEs01 733 CALL GETDSK - 03AF 32rFBs07 734 LD (CDRIVE),A ; SET CURRENT DRIVE. - 03B2 CDr48s02 735 CALL CONVFST ; CONVERT NAME TYPED IN. - 03B5 C4rF3s01 736 CALL NZ,SYNERR ; WILD CARDS ARE NOT ALLOWED. - 03B8 3ArFCs07 737 LD A,(CHGDRV) ; IF A CHANGE IN DRIVES WAS INDICATED, - 03BB B7 738 OR A ; THEN TREAT THIS AS AN UNKNOWN COMMAND - 03BC C2r9Es06 739 JP NZ,UNKNOWN ; WHICH GETS EXECUTED. - 03BF CDr26s03 740 CALL SEARCH ; ELSE SEARCH COMMAND TABLE FOR A MATCH. - 741 ; - 742 ; NOTE THAT AN UNKNOWN COMMAND RETURNS - 743 ; WITH (A) POINTING TO THE LAST ADDRESS - 744 ; IN OUR TABLE WHICH IS (UNKNOWN). - 745 ; - 03C2 21r16s03 746 LD HL,#CMDADR ; NOW, LOOK THRU OUR ADDRESS TABLE FOR COMMAND (A). - 03C5 5F 747 LD E,A ; SET (DE) TO COMMAND NUMBER. - 03C6 16 00 748 LD D,#0 - 03C8 19 749 ADD HL,DE - 03C9 19 750 ADD HL,DE ; (HL)=(CMDADR)+2*(COMMAND NUMBER). - 03CA 7E 751 LD A,(HL) ; NOW PICK OUT THIS ADDRESS. - 03CB 23 752 INC HL - 03CC 66 753 LD H,(HL) - 03CD 6F 754 LD L,A - 03CE E9 755 JP (HL) ; NOW EXECUTE IT. - 756 ; - 757 ; READ ERROR WHILE TYPEING A FILE. - 758 ; - 03CF 01rD5s03 759 RDERROR:LD BC,#RDERR - 03D2 C3rA5s00 760 JP PLINE - 03D5 52 65 61 64 20 45 761 RDERR: .asciz "Read Error" - 72 72 6F 72 00 - 762 - 763 ; - 764 ; R.EQUIRED FILE WAS NOT LOCATED. - 765 ; - 03E0 01rE6s03 766 NONE: LD BC,#NOFILE - 03E3 C3rA5s00 767 JP PLINE - 03E6 4E 6F 20 46 69 6C 768 NOFILE: .asciz "No File" - 65 00 - 769 ; - 770 ; DECODE A COMMAND OF THE FORM 'A>FILENAME NUMBER{ FILENAME}. - 771 ; NOTE THAT A DRIVE SPECIFIER IS NOT ALLOWED ON THE FIRST FILE - 772 ; NAME. ON RETURN, THE NUMBER IS IN REGISTER (A). ANY ERROR - 773 ; CAUSES 'FILENAME?' TO BE PRINTED AND THE COMMAND IS ABORTED. - 774 ; - 03EE CDr48s02 775 DECODE: CALL CONVFST ; CONVERT FILENAME. - 03F1 3ArFCs07 776 LD A,(CHGDRV) ; DO NOT ALLOW A DRIVE TO BE SPECIFIED. - 03F4 B7 777 OR A - 03F5 C2rF3s01 778 JP NZ,SYNERR - 03F8 21rDAs07 779 LD HL,#FCB+1 ; CONVERT NUMBER NOW. - 03FB 01 0B 00 780 LD BC,#11 ; (B)=SUM REGISTER, (C)=MAX DIGIT COUNT. - 03FE 7E 781 DECODE1:LD A,(HL) - 03FF FE 20 782 CP #ASCSPACE ; A SPACE TERMINATES THE NUMERAL. - 0401 CAr29s04 783 JP Z,DECODE3 - 0404 23 784 INC HL - 0405 D6 30 785 SUB #0x30 ; MAKE BINARY FROM ASCII. - 0407 FE 0A 786 CP #10 ; LEGAL DIGIT? - 0409 D2rF3s01 787 JP NC,SYNERR - 040C 57 788 LD D,A ; YES, SAVE IT IN (D). - 040D 78 789 LD A,B ; COMPUTE (B)=(B)*10 AND CHECK FOR OVERFLOW. - 040E E6 E0 790 AND #0x0E0 - 0410 C2rF3s01 791 JP NZ,SYNERR - 0413 78 792 LD A,B - 0414 07 793 RLCA - 0415 07 794 RLCA - 0416 07 795 RLCA ; (A)=(B)*8 - 0417 80 796 ADD A,B ; .......*9 - 0418 DArF3s01 797 JP C,SYNERR - 041B 80 798 ADD A,B ; .......*10 - 041C DArF3s01 799 JP C,SYNERR - 041F 82 800 ADD A,D ; ADD IN NEW DIGIT NOW. - 0420 DArF3s01 801 DECODE2:JP C,SYNERR - 0423 47 802 LD B,A ; AND SAVE RESULT. - 0424 0D 803 DEC C ; ONLY LOOK AT 11 DIGITS. - 0425 C2rFEs03 804 JP NZ,DECODE1 - 0428 C9 805 RET - 0429 7E 806 DECODE3:LD A,(HL) ; SPACES MUST FOLLOW (WHY?). - 042A FE 20 807 CP #ASCSPACE - 042C C2rF3s01 808 JP NZ,SYNERR - 042F 23 809 INC HL - 0430 0D 810 DECODE4:DEC C - 0431 C2r29s04 811 JP NZ,DECODE3 - 0434 78 812 LD A,B ; SET (A)=THE NUMERIC VALUE ENTERED. - 0435 C9 813 RET - 814 ; - 815 ; MOVE 3 BYTES FROM (HL) TO (DE). NOTE THAT THERE IS ONLY - 816 ; ONE REFERENCE TO THIS AT (A2D5H). - 817 ; - 0436 06 03 818 MOVE3: LD B,#3 - 819 ; - 820 ; MOVE (B) BYTES FROM (HL) TO (DE). - 821 ; - 0438 7E 822 HL2DE: LD A,(HL) - 0439 12 823 LD (DE),A - 043A 23 824 INC HL - 043B 13 825 INC DE - 043C 05 826 DEC B - 043D C2r38s04 827 JP NZ,HL2DE - 0440 C9 828 RET - 829 ; - 830 ; COMPUTE (HL)=(TBUFF)+(A)+(C) AND GET THE BYTE THAT'S HERE. - 831 ; - 0441 21 80 00 832 EXTRACT:LD HL,#TBUFF - 0444 81 833 ADD A,C - 0445 CDr43s02 834 CALL ADDHL - 0448 7E 835 LD A,(HL) - 0449 C9 836 RET - 837 ; - 838 ; CHECK DRIVE SPECIFIED. IF IT MEANS A CHANGE, THEN THE NEW - 839 ; DRIVE WILL BE SELECTED. IN ANY CASE, THE DRIVE BYTE OF THE - 840 ; FCB WILL BE SET TO NULL (MEANS USE CURRENT DRIVE). - 841 ; - 044A AF 842 DSELECT:XOR A ; NULL OUT FIRST BYTE OF FCB. - 044B 32rD9s07 843 LD (FCB),A - 044E 3ArFCs07 844 LD A,(CHGDRV) ; A DRIVE CHANGE INDICATED? - 0451 B7 845 OR A - 0452 C8 846 RET Z - 0453 3D 847 DEC A ; YES, IS IT THE SAME AS THE CURRENT DRIVE? - 0454 21rFBs07 848 LD HL,#CDRIVE - 0457 BE 849 CP (HL) - 0458 C8 850 RET Z - 0459 C3rBBs00 851 JP DSKSEL ; NO. SELECT IT THEN. - 852 ; - 853 ; CHECK THE DRIVE SELECTION AND RESET IT TO THE PREVIOUS - 854 ; DRIVE IF IT WAS CHANGED FOR THE PRECEEDING COMMAND. - 855 ; - 045C 3ArFCs07 856 RESETDR:LD A,(CHGDRV) ; DRIVE CHANGE INDICATED? - 045F B7 857 OR A - 0460 C8 858 RET Z - 0461 3D 859 DEC A ; YES, WAS IT A DIFFERENT DRIVE? - 0462 21rFBs07 860 LD HL,#CDRIVE - 0465 BE 861 CP (HL) - 0466 C8 862 RET Z - 0467 3ArFBs07 863 LD A,(CDRIVE) ; YES, RE-SELECT OUR OLD DRIVE. - 046A C3rBBs00 864 JP DSKSEL - 865 - 0001 866 .IF MON - 867 ; - 868 ;************************************************************** - 869 ;* - 870 ;* M O N I T O R C O M M A N D - 871 ;* - 872 ;************************************************************** - 873 ; - 046D C3 00 FC 874 MONITOR: JP MONADR - 875 .ENDIF - 876 - 877 ; - 878 ;************************************************************** - 879 ;* - 880 ;* D I R E C T O R Y C O M M A N D - 881 ;* - 882 ;************************************************************** - 883 ; - 0470 CDr48s02 884 DIRECT: CALL CONVFST ; CONVERT FILE NAME. - 0473 CDr4As04 885 CALL DSELECT ; SELECT INDICATED DRIVE. - 0476 21rDAs07 886 LD HL,#FCB+1 ; WAS ANY FILE INDICATED? - 0479 7E 887 LD A,(HL) - 047A FE 20 888 CP #ASCSPACE - 047C C2r88s04 889 JP NZ,DIRECT2 - 047F 06 0B 890 LD B,#11 ; NO. FILL FIELD WITH '?' - SAME AS *.*. - 0481 36 3F 891 DIRECT1:LD (HL),#QUESTION - 0483 23 892 INC HL - 0484 05 893 DEC B - 0485 C2r81s04 894 JP NZ,DIRECT1 - 0488 1E 00 895 DIRECT2:LD E,#0 ; SET INITIAL CURSOR POSITION. - 048A D5 896 PUSH DE - 048B CDrE7s00 897 CALL SRCHFCB ; GET FIRST FILE NAME. - 048E CCrE0s03 898 CALL Z,NONE ; NONE FOUND AT ALL? - 0491 CAr14s05 899 DIRECT3:JP Z,DIRECT9 ; TERMINATE IF NO MORE NAMES. - 0494 3ArFAs07 900 LD A,(RTNCODE) ; GET FILE'S POSITION IN SEGMENT (0-3). - 0497 0F 901 RRCA - 0498 0F 902 RRCA - 0499 0F 903 RRCA - 049A E6 60 904 AND #0x60 ; (A)=POSITION*32 - 049C 4F 905 LD C,A - 049D 3E 0A 906 LD A,#10 - 049F CDr41s04 907 CALL EXTRACT ; EXTRACT THE TENTH ENTRY IN FCB. - 04A2 17 908 RLA ; CHECK SYSTEM FILE STATUS BIT. - 04A3 DAr08s05 909 JP C,DIRECT8 ; WE DON'T LIST THEM. - 04A6 D1 910 POP DE - 04A7 7B 911 LD A,E ; BUMP NAME COUNT. - 04A8 1C 912 INC E - 04A9 D5 913 PUSH DE - 04AA E6 03 914 AND #3 ; AT END OF LINE? - 04AC F5 915 PUSH AF - 04AD C2rC5s04 916 JP NZ,DIRECT4 - 04B0 CDr96s00 917 CALL CRLF ; YES, END THIS LINE AND START ANOTHER. - 04B3 C5 918 PUSH BC - 04B4 CDrCEs01 919 CALL GETDSK ; START LINE WITH ('A:'). - 04B7 C1 920 POP BC - 04B8 C6 41 921 ADD A,#0x41 - 04BA CDr90s00 922 CALL PRINTB - 04BD 3E 3A 923 LD A,#COLON - 04BF CDr90s00 924 CALL PRINTB - 04C2 C3rCDs04 925 JP DIRECT5 - 04C5 CDrA0s00 926 DIRECT4:CALL SPACE ; ADD SEPERATOR BETWEEN FILE NAMES. - 04C8 3E 3A 927 LD A,#COLON - 04CA CDr90s00 928 CALL PRINTB - 04CD CDrA0s00 929 DIRECT5:CALL SPACE - 04D0 06 01 930 LD B,#1 ; 'EXTRACT' EACH FILE NAME CHARACTER AT A TIME. - 04D2 78 931 DIRECT6:LD A,B - 04D3 CDr41s04 932 CALL EXTRACT - 04D6 E6 7F 933 AND #0x7F ; STRIP BIT 7 (STATUS BIT). - 04D8 FE 20 934 CP #ASCSPACE ; ARE WE AT THE END OF THE NAME? - 04DA C2rF2s04 935 JP NZ,DRECT65 - 04DD F1 936 POP AF ; YES, DON'T PRINT SPACES AT THE END OF A LINE. - 04DE F5 937 PUSH AF - 04DF FE 03 938 CP #3 - 04E1 C2rF0s04 939 JP NZ,DRECT63 - 04E4 3E 09 940 LD A,#9 ; FIRST CHECK FOR NO EXTENSION. - 04E6 CDr41s04 941 CALL EXTRACT - 04E9 E6 7F 942 AND #0x7F - 04EB FE 20 943 CP #ASCSPACE - 04ED CAr07s05 944 JP Z,DIRECT7 ; DON'T PRINT SPACES. - 04F0 3E 20 945 DRECT63:LD A,#ASCSPACE ; ELSE PRINT THEM. - 04F2 CDr90s00 946 DRECT65:CALL PRINTB - 04F5 04 947 INC B ; BUMP TO NEXT CHARACTER PSOITION. - 04F6 78 948 LD A,B - 04F7 FE 0C 949 CP #12 ; END OF THE NAME? - 04F9 D2r07s05 950 JP NC,DIRECT7 - 04FC FE 09 951 CP #9 ; NOPE, STARTING EXTENSION? - 04FE C2rD2s04 952 JP NZ,DIRECT6 - 0501 CDrA0s00 953 CALL SPACE ; YES, ADD SEPERATING SPACE. - 0504 C3rD2s04 954 JP DIRECT6 - 0507 F1 955 DIRECT7:POP AF ; GET THE NEXT FILE NAME. - 0508 CDrC0s01 956 DIRECT8:CALL CHKCON ; FIRST CHECK CONSOLE, QUIT ON ANYTHING. - 050B C2r14s05 957 JP NZ,DIRECT9 - 050E CDrE2s00 958 CALL SRCHNXT ; GET NEXT NAME. - 0511 C3r91s04 959 JP DIRECT3 ; AND CONTINUE WITH OUR LIST. - 0514 D1 960 DIRECT9:POP DE ; RESTORE THE STACK AND RETURN TO COMMAND LEVEL. - 0515 C3r92s07 961 JP GETBACK - 962 ; - 963 ;************************************************************** - 964 ;* - 965 ;* E R A S E C O M M A N D - 966 ;* - 967 ;************************************************************** - 968 ; - 0518 CDr48s02 969 ERASE: CALL CONVFST ; CONVERT FILE NAME. - 051B FE 0B 970 CP #11 ; WAS '*.*' ENTERED? - 051D C2r3Bs05 971 JP NZ,ERASE1 - 0520 01r4Bs05 972 LD BC,#YESNO ; YES, ASK FOR CONFIRMATION. - 0523 CDrA5s00 973 CALL PLINE - 0526 CDr37s01 974 CALL GETINP - 0529 21r07s00 975 LD HL,#INBUFF+1 - 052C 35 976 DEC (HL) ; MUST BE EXACTLY 'Y'. - 052D C2r7As03 977 JP NZ,CMMND1 - 0530 23 978 INC HL - 0531 7E 979 LD A,(HL) - 0532 FE 59 980 CP #0x59 - 0534 C2r7As03 981 JP NZ,CMMND1 - 0537 23 982 INC HL - 0538 22r86s00 983 LD (INPOINT),HL ; SAVE INPUT LINE POINTER. - 053B CDr4As04 984 ERASE1: CALL DSELECT ; SELECT DESIRED DISK. - 053E 11rD9s07 985 LD DE,#FCB - 0541 CDrEDs00 986 CALL DELETE ; DELETE THE FILE. - 0544 3C 987 INC A - 0545 CCrE0s03 988 CALL Z,NONE ; NOT THERE? - 0548 C3r92s07 989 JP GETBACK ; RETURN TO COMMAND LEVEL NOW. - 054B 41 6C 6C 20 28 59 990 YESNO: .asciz "All (Y/N)?" - 2F 4E 29 3F 00 - 991 ; - 992 ;************************************************************** - 993 ;* - 994 ;* T Y P E C O M M A N D - 995 ;* - 996 ;************************************************************** - 997 ; - 0556 CDr48s02 998 TYPE: CALL CONVFST ; CONVERT FILE NAME. - 0559 C2rF3s01 999 JP NZ,SYNERR ; WILD CARDS NOT ALLOWED. - 055C CDr4As04 1000 CALL DSELECT ; SELECT INDICATED DRIVE. - 055F CDrCEs00 1001 CALL OPENFCB ; OPEN THE FILE. - 0562 CArA0s05 1002 JP Z,TYPE5 ; NOT THERE? - 0565 CDr96s00 1003 CALL CRLF ; OK, START A NEW LINE ON THE SCREEN. - 0568 21rFDs07 1004 LD HL,#NBYTES ; INITIALIZE BYTE COUNTER. - 056B 36 FF 1005 LD (HL),#0x0FF ; SET TO READ FIRST SECTOR. - 056D 21rFDs07 1006 TYPE1: LD HL,#NBYTES - 0570 7E 1007 TYPE2: LD A,(HL) ; HAVE WE WRITTEN THE ENTIRE SECTOR? - 0571 FE 80 1008 CP #128 - 0573 DAr80s05 1009 JP C,TYPE3 - 0576 E5 1010 PUSH HL ; YES, READ IN THE NEXT ONE. - 0577 CDrFCs00 1011 CALL READFCB - 057A E1 1012 POP HL - 057B C2r99s05 1013 JP NZ,TYPE4 ; END OR ERROR? - 057E AF 1014 XOR A ; OK, CLEAR BYTE COUNTER. - 057F 77 1015 LD (HL),A - 0580 34 1016 TYPE3: INC (HL) ; COUNT THIS BYTE. - 0581 21 80 00 1017 LD HL,#TBUFF ; AND GET THE (A)TH ONE FROM THE BUFFER (TBUFF). - 0584 CDr43s02 1018 CALL ADDHL - 0587 7E 1019 LD A,(HL) - 0588 FE 1A 1020 CP #CNTRLZ ; END OF FILE MARK? - 058A CAr92s07 1021 JP Z,GETBACK - 058D CDr8As00 1022 CALL PRINT ; NO, PRINT IT. - 0590 CDrC0s01 1023 CALL CHKCON ; CHECK CONSOLE, QUIT IF ANYTHING READY. - 0593 C2r92s07 1024 JP NZ,GETBACK - 0596 C3r6Ds05 1025 JP TYPE1 - 1026 ; - 1027 ; GET HERE ON AN END OF FILE OR READ ERROR. - 1028 ; - 0599 3D 1029 TYPE4: DEC A ; READ ERROR? - 059A CAr92s07 1030 JP Z,GETBACK - 059D CDrCFs03 1031 CALL RDERROR ; YES, PRINT MESSAGE. - 05A0 CDr5Cs04 1032 TYPE5: CALL RESETDR ; AND RESET PROPER DRIVE - 05A3 C3rF3s01 1033 JP SYNERR ; NOW PRINT FILE NAME WITH PROBLEM. - 1034 ; - 1035 ;************************************************************** - 1036 ;* - 1037 ;* S A V E C O M M A N D - 1038 ;* - 1039 ;************************************************************** - 1040 ; - 05A6 CDrEEs03 1041 SAVE: CALL DECODE ; GET NUMERIC NUMBER THAT FOLLOWS SAVE. - 05A9 F5 1042 PUSH AF ; SAVE NUMBER OF PAGES TO WRITE. - 05AA CDr48s02 1043 CALL CONVFST ; CONVERT FILE NAME. - 05AD C2rF3s01 1044 JP NZ,SYNERR ; WILD CARDS NOT ALLOWED. - 05B0 CDr4As04 1045 CALL DSELECT ; SELECT SPECIFIED DRIVE. - 05B3 11rD9s07 1046 LD DE,#FCB ; NOW DELETE THIS FILE. - 05B6 D5 1047 PUSH DE - 05B7 CDrEDs00 1048 CALL DELETE - 05BA D1 1049 POP DE - 05BB CDr07s01 1050 CALL CREATE ; AND CREATE IT AGAIN. - 05BE CArF4s05 1051 JP Z,SAVE3 ; CAN'T CREATE? - 05C1 AF 1052 XOR A ; CLEAR RECORD NUMBER BYTE. - 05C2 32rF9s07 1053 LD (FCB+32),A - 05C5 F1 1054 POP AF ; CONVERT PAGES TO SECTORS. - 05C6 6F 1055 LD L,A - 05C7 26 00 1056 LD H,#0 - 05C9 29 1057 ADD HL,HL ; (HL)=NUMBER OF SECTORS TO WRITE. - 05CA 11 00 01 1058 LD DE,#TBASE ; AND WE START FROM HERE. - 05CD 7C 1059 SAVE1: LD A,H ; DONE YET? - 05CE B5 1060 OR L - 05CF CArEAs05 1061 JP Z,SAVE2 - 05D2 2B 1062 DEC HL ; NOPE, COUNT THIS AND COMPUTE THE START - 05D3 E5 1063 PUSH HL ; OF THE NEXT 128 BYTE SECTOR. - 05D4 21 80 00 1064 LD HL,#128 - 05D7 19 1065 ADD HL,DE - 05D8 E5 1066 PUSH HL ; SAVE IT AND SET THE TRANSFER ADDRESS. - 05D9 CDrD6s01 1067 CALL DMASET - 05DC 11rD9s07 1068 LD DE,#FCB ; WRITE OUT THIS SECTOR NOW. - 05DF CDr02s01 1069 CALL WRTREC - 05E2 D1 1070 POP DE ; RESET (DE) TO THE START OF THE LAST SECTOR. - 05E3 E1 1071 POP HL ; RESTORE SECTOR COUNT. - 05E4 C2rF4s05 1072 JP NZ,SAVE3 ; WRITE ERROR? - 05E7 C3rCDs05 1073 JP SAVE1 - 1074 ; - 1075 ; GET HERE AFTER WRITING ALL OF THE FILE. - 1076 ; - 05EA 11rD9s07 1077 SAVE2: LD DE,#FCB ; NOW CLOSE THE FILE. - 05ED CDrD8s00 1078 CALL CLOSE - 05F0 3C 1079 INC A ; DID IT CLOSE OK? - 05F1 C2rFAs05 1080 JP NZ,SAVE4 - 1081 ; - 1082 ; PRINT OUT ERROR MESSAGE (NO SPACE). - 1083 ; - 05F4 01r00s06 1084 SAVE3: LD BC,#NOSPACE - 05F7 CDrA5s00 1085 CALL PLINE - 05FA CDrD3s01 1086 SAVE4: CALL STDDMA ; RESET THE STANDARD DMA ADDRESS. - 05FD C3r92s07 1087 JP GETBACK - 1088 - 0600 4E 6F 20 53 70 61 1089 NOSPACE: .asciz "No Space" - 63 65 00 - 1090 ; - 1091 ;************************************************************** - 1092 ;* - 1093 ;* R E N A M E C O M M A N D - 1094 ;* - 1095 ;************************************************************** - 1096 ; - 0609 CDr48s02 1097 RENAME: CALL CONVFST ; CONVERT FIRST FILE NAME. - 060C C2rF3s01 1098 JP NZ,SYNERR ; WILD CARDS NOT ALLOWED. - 060F 3ArFCs07 1099 LD A,(CHGDRV) ; REMEMBER ANY CHANGE IN DRIVES SPECIFIED. - 0612 F5 1100 PUSH AF - 0613 CDr4As04 1101 CALL DSELECT ; AND SELECT THIS DRIVE. - 0616 CDrE7s00 1102 CALL SRCHFCB ; IS THIS FILE PRESENT? - 0619 C2r72s06 1103 JP NZ,RENAME6 ; YES, PRINT ERROR MESSAGE. - 061C 21rD9s07 1104 LD HL,#FCB ; YES, MOVE THIS NAME INTO SECOND SLOT. - 061F 11rE9s07 1105 LD DE,#FCB+16 - 0622 06 10 1106 LD B,#16 - 0624 CDr38s04 1107 CALL HL2DE - 0627 2Ar86s00 1108 LD HL,(INPOINT) ; GET INPUT POINTER. - 062A EB 1109 EX DE,HL - 062B CDr39s02 1110 CALL NONBLANK ; GET NEXT NON BLANK CHARACTER. - 062E FE 3D 1111 CP #EQUAL ; ONLY ALLOW AN '=' OR '_' SEPERATOR. - 0630 CAr38s06 1112 JP Z,RENAME1 - 0633 FE 20 1113 CP #ASCSPACE - 0635 C2r6Cs06 1114 JP NZ,RENAME5 - 0638 EB 1115 RENAME1:EX DE,HL - 0639 23 1116 INC HL ; OK, SKIP SEPERATOR. - 063A 22r86s00 1117 LD (INPOINT),HL ; SAVE INPUT LINE POINTER. - 063D CDr48s02 1118 CALL CONVFST ; CONVERT THIS SECOND FILE NAME NOW. - 0640 C2r6Cs06 1119 JP NZ,RENAME5 ; AGAIN, NO WILD CARDS. - 0643 F1 1120 POP AF ; IF A DRIVE WAS SPECIFIED, THEN IT - 0644 47 1121 LD B,A ; MUST BE THE SAME AS BEFORE. - 0645 21rFCs07 1122 LD HL,#CHGDRV - 0648 7E 1123 LD A,(HL) - 0649 B7 1124 OR A - 064A CAr52s06 1125 JP Z,RENAME2 - 064D B8 1126 CP B - 064E 70 1127 LD (HL),B - 064F C2r6Cs06 1128 JP NZ,RENAME5 ; THEY WERE DIFFERENT, ERROR. - 0652 70 1129 RENAME2:LD (HL),B ; RESET AS PER THE FIRST FILE SPECIFICATION. - 0653 AF 1130 XOR A - 0654 32rD9s07 1131 LD (FCB),A ; CLEAR THE DRIVE BYTE OF THE FCB. - 0657 CDrE7s00 1132 RENAME3:CALL SRCHFCB ; AND GO LOOK FOR SECOND FILE. - 065A CAr66s06 1133 JP Z,RENAME4 ; DOESN'T EXIST? - 065D 11rD9s07 1134 LD DE,#FCB - 0660 CDr0Cs01 1135 CALL RENAM ; OK, RENAME THE FILE. - 0663 C3r92s07 1136 JP GETBACK - 1137 ; - 1138 ; PROCESS RENAME ERRORS HERE. - 1139 ; - 0666 CDrE0s03 1140 RENAME4:CALL NONE ; FILE NOT THERE. - 0669 C3r92s07 1141 JP GETBACK - 066C CDr5Cs04 1142 RENAME5:CALL RESETDR ; BAD COMMAND FORMAT. - 066F C3rF3s01 1143 JP SYNERR - 0672 01r7Bs06 1144 RENAME6:LD BC,#EXISTS ; DESTINATION FILE ALREADY EXISTS. - 0675 CDrA5s00 1145 CALL PLINE - 0678 C3r92s07 1146 JP GETBACK - 067B 46 69 6C 65 20 45 1147 EXISTS: .asciz "File Exists" - 78 69 73 74 73 00 - 1148 ; - 1149 ;************************************************************** - 1150 ;* - 1151 ;* U S E R C O M M A N D - 1152 ;* - 1153 ;************************************************************** - 1154 ; - 0687 CDrEEs03 1155 USER: CALL DECODE ; GET NUMERIC VALUE FOLLOWING COMMAND. - 068A FE 10 1156 CP #16 ; LEGAL USER NUMBER? - 068C D2rF3s01 1157 JP NC,SYNERR - 068F 5F 1158 LD E,A ; YES BUT IS THERE ANYTHING ELSE? - 0690 3ArDAs07 1159 LD A,(FCB+1) - 0693 FE 20 1160 CP #ASCSPACE - 0695 CArF3s01 1161 JP Z,SYNERR ; YES, THAT IS NOT ALLOWED. - 0698 CDr13s01 1162 CALL GETSETUC ; OK, SET USER CODE. - 069B C3r95s07 1163 JP GETBACK1 - 1164 ; - 1165 ;************************************************************** - 1166 ;* - 1167 ;* T R A N S I A N T P R O G R A M C O M M A N D - 1168 ;* - 1169 ;************************************************************** - 1170 ; - 069E 3ArDAs07 1171 UNKNOWN:LD A,(FCB+1) ; ANYTHING TO EXECUTE? - 06A1 FE 20 1172 CP #ASCSPACE - 06A3 C2rBAs06 1173 JP NZ,UNKWN1 - 06A6 3ArFCs07 1174 LD A,(CHGDRV) ; NOPE, ONLY A DRIVE CHANGE? - 06A9 B7 1175 OR A - 06AA CAr95s07 1176 JP Z,GETBACK1 ; NEITHER??? - 06AD 3D 1177 DEC A - 06AE 32rFBs07 1178 LD (CDRIVE),A ; OK, STORE NEW DRIVE. - 06B1 CDr27s01 1179 CALL MOVECD ; SET (TDRIVE) ALSO. - 06B4 CDrBBs00 1180 CALL DSKSEL ; AND SELECT THIS DRIVE. - 06B7 C3r95s07 1181 JP GETBACK1 ; THEN RETURN. - 1182 ; - 1183 ; HERE A FILE NAME WAS TYPED. PREPARE TO EXECUTE IT. - 1184 ; - 06BA 11rE2s07 1185 UNKWN1: LD DE,#FCB+9 ; AN EXTENSION SPECIFIED? - 06BD 1A 1186 LD A,(DE) - 06BE FE 20 1187 CP #ASCSPACE - 06C0 C2rF3s01 1188 JP NZ,SYNERR ; YES, NOT ALLOWED. - 06C3 D5 1189 UNKWN2: PUSH DE - 06C4 CDr4As04 1190 CALL DSELECT ; SELECT SPECIFIED DRIVE. - 06C7 D1 1191 POP DE - 06C8 21r8Fs07 1192 LD HL,#COMFILE ; SET THE EXTENSION TO 'COM'. LD HL,COMFILE - 06CB CDr36s04 1193 CALL MOVE3 ; move 3 bytes from (HL) to (DE) to add .COM - 06CE CDrCEs00 1194 CALL OPENFCB ; AND OPEN THIS FILE. - 06D1 C2rEAs06 1195 JP NZ,UNKWNA ;GOT IT - 0001 1196 .IF CHKU0B - 06D4 1E 00 1197 LD E,#0 ;TRY USER 0, THIS DRIVE - 06D6 CDr13s01 1198 CALL GETSETUC ; OK, SET USER CODE. - 06D9 CDrCEs00 1199 CALL OPENFCB - 06DC C2rEAs06 1200 JP NZ,UNKWNA ;GOT IT - 06DF 21rD9s07 1201 LD HL,#FCB ;SEE IF ON DRIVE B, USER 0 - 06E2 36 02 1202 LD (HL),#2 - 06E4 CDrCEs00 1203 CALL OPENFCB - 06E7 CAr77s07 1204 JP Z,UNKWN9 ;NOPE - 1205 .ENDIF - 1206 ; - 1207 ; LOAD IN THE PROGRAM. - 1208 ; - 06EA 21 00 01 1209 UNKWNA: LD HL,#TBASE ; STORE THE PROGRAM STARTING HERE. - 06ED E5 1210 UNKWN3: PUSH HL - 06EE EB 1211 EX DE,HL - 06EF CDrD6s01 1212 CALL DMASET ; SET TRANSFER ADDRESS. - 06F2 11rD9s07 1213 LD DE,#FCB ; AND READ THE NEXT RECORD. - 06F5 CDrF7s00 1214 CALL RDREC - 06F8 C2r0Ds07 1215 JP NZ,UNKWN4 ; END OF FILE OR READ ERROR? - 06FB E1 1216 POP HL ; NOPE, BUMP POINTER FOR NEXT SECTOR. - 06FC 11 80 00 1217 LD DE,#128 - 06FF 19 1218 ADD HL,DE - 0700 11r00s00 1219 LD DE,#CBASE ; ENOUGH ROOM FOR THE WHOLE FILE? - 0703 7D 1220 LD A,L - 0704 93 1221 SUB E - 0705 7C 1222 LD A,H - 0706 9A 1223 SBC A,D - 0707 D2r7Ds07 1224 JP NC,UNKWN0 ; NO, IT CAN'T FIT. - 070A C3rEDs06 1225 JP UNKWN3 - 1226 ; - 1227 ; GET HERE AFTER FINISHED READING. - 1228 ; - 070D E1 1229 UNKWN4: POP HL - 070E 3D 1230 DEC A ; NORMAL END OF FILE? - 070F C2r7Ds07 1231 JP NZ,UNKWN0 - 0712 CDr5Cs04 1232 CALL RESETDR ; YES, RESET PREVIOUS DRIVE. - 0715 CDr48s02 1233 CALL CONVFST ; CONVERT THE FIRST FILE NAME THAT FOLLOWS - 0718 21rFCs07 1234 LD HL,#CHGDRV ; COMMAND NAME. - 071B E5 1235 PUSH HL - 071C 7E 1236 LD A,(HL) ; SET DRIVE CODE IN DEFAULT FCB. - 071D 32rD9s07 1237 LD (FCB),A - 0720 3E 10 1238 LD A,#16 ; PUT SECOND NAME 16 BYTES LATER. - 0722 CDr4As02 1239 CALL CONVERT ; CONVERT SECOND FILE NAME. - 0725 E1 1240 POP HL - 0726 7E 1241 LD A,(HL) ; AND SET THE DRIVE FOR THIS SECOND FILE. - 0727 32rE9s07 1242 LD (FCB+16),A - 072A AF 1243 XOR A ; CLEAR RECORD BYTE IN FCB. - 072B 32rF9s07 1244 LD (FCB+32),A - 072E 11 5C 00 1245 LD DE,#TFCB ; MOVE IT INTO PLACE AT(005CH). - 0731 21rD9s07 1246 LD HL,#FCB - 0734 06 21 1247 LD B,#33 - 0736 CDr38s04 1248 CALL HL2DE - 0739 21r08s00 1249 LD HL,#INBUFF+2 ; NOW MOVE THE REMAINDER OF THE INPUT - 073C 7E 1250 UNKWN5: LD A,(HL) ; LINE DOWN TO (0080H). LOOK FOR A NON BLANK. - 073D B7 1251 OR A ; OR A NULL. - 073E CAr4As07 1252 JP Z,UNKWN6 - 0741 FE 20 1253 CP #ASCSPACE - 0743 CAr4As07 1254 JP Z,UNKWN6 - 0746 23 1255 INC HL - 0747 C3r3Cs07 1256 JP UNKWN5 - 1257 ; - 1258 ; DO THE LINE MOVE NOW. IT ENDS IN A NULL BYTE. - 1259 ; - 074A 06 00 1260 UNKWN6: LD B,#0 ; KEEP A CHARACTER COUNT. - 074C 11 81 00 1261 LD DE,#TBUFF+1 ; DATA GETS PUT HERE. - 074F 7E 1262 UNKWN7: LD A,(HL) ; MOVE IT NOW. - 0750 12 1263 LD (DE),A - 0751 B7 1264 OR A - 0752 CAr5Bs07 1265 JP Z,UNKWN8 - 0755 04 1266 INC B - 0756 23 1267 INC HL - 0757 13 1268 INC DE - 0758 C3r4Fs07 1269 JP UNKWN7 - 075B 78 1270 UNKWN8: LD A,B ; NOW STORE THE CHARACTER COUNT. - 075C 32 80 00 1271 LD (TBUFF),A - 075F CDr96s00 1272 CALL CRLF ; CLEAN UP THE SCREEN. - 0762 CDrD3s01 1273 CALL STDDMA ; SET STANDARD TRANSFER ADDRESS. - 0765 CDr18s01 1274 CALL SETCDRV ; RESET CURRENT DRIVE. - 0768 CD 00 01 1275 CALL TBASE ; AND EXECUTE THE PROGRAM. - 1276 ; - 1277 ; TRANSIANT PROGRAMS RETURN HERE (OR REBOOT). - 1278 ; - 076B 31rB7s07 1279 LD SP,#BATCH ; SET STACK FIRST OFF. - 076E CDr27s01 1280 CALL MOVECD ; MOVE CURRENT DRIVE INTO PLACE (TDRIVE). - 0771 CDrBBs00 1281 CALL DSKSEL ; AND RESELECT IT. - 0774 C3r7As03 1282 JP CMMND1 ; BACK TO COMAND MODE. - 1283 ; - 1284 ; GET HERE IF SOME ERROR OCCURED. - 1285 ; - 0777 CDr5Cs04 1286 UNKWN9: CALL RESETDR ; INPROPER FORMAT. - 077A C3rF3s01 1287 JP SYNERR - 077D 01r86s07 1288 UNKWN0: LD BC,#BADLOAD ; READ ERROR OR WON'T FIT. - 0780 CDrA5s00 1289 CALL PLINE - 0783 C3r92s07 1290 JP GETBACK - 0786 42 61 64 20 4C 6F 1291 BADLOAD:.asciz "Bad Load" - 61 64 00 - 078F 43 4F 4D 1292 COMFILE:.ascii "COM" ; COMMAND FILE EXTENSION. - 1293 ; - 1294 ; GET HERE TO RETURN TO COMMAND LEVEL. WE WILL RESET THE - 1295 ; PREVIOUS ACTIVE DRIVE AND THEN EITHER RETURN TO COMMAND - 1296 ; LEVEL DIRECTLY OR PRINT ERROR MESSAGE AND THEN RETURN. - 1297 ; - 0792 CDr5Cs04 1298 GETBACK:CALL RESETDR ; RESET PREVIOUS DRIVE. - 0795 1299 GETBACK1: - 0795 CDr48s02 1300 CALL CONVFST ; CONVERT FIRST NAME IN (FCB). - 0798 3ArDAs07 1301 LD A,(FCB+1) ; IF THIS WAS JUST A DRIVE CHANGE R.EQUEST, - 079B D6 20 1302 SUB #ASCSPACE ; MAKE SURE IT WAS VALID. - 079D 21rFCs07 1303 LD HL,#CHGDRV - 07A0 B6 1304 OR (HL) - 07A1 C2rF3s01 1305 JP NZ,SYNERR - 07A4 C3r7As03 1306 JP CMMND1 ; OK, RETURN TO COMMAND LEVEL. - 1307 ; - 1308 ; CCP STACK AREA. - 1309 ; - 07A7 00 00 00 00 00 00 1310 .DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - 00 00 00 00 00 00 - 00 00 00 00 - 07B7 1311 CCPSTACK: - 1312 ;dwg; .EQU $ ;END OF CCP STACK AREA. - 1313 - 1314 ; - 1315 ; BATCH (OR SUBMIT) PROCESSING INFORMATION STORAGE. - 1316 ; - 07B7 00 1317 BATCH: .DB 0 ; BATCH MODE FLAG (0=NOT ACTIVE). - 07B8 00 1318 BATCHFCB:.DB 0 - 07B9 24 24 24 20 20 20 1319 .ascii "$$$ SUB" - 20 20 53 55 42 - 07C4 00 00 00 00 00 00 1320 .DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - 00 00 00 00 00 00 - 00 00 00 00 00 00 - 00 00 00 - 1321 ; - 1322 ; FILE CONTROL BLOCK SETUP BY THE CCP. - 1323 ; - 07D9 00 1324 FCB: .DB 0 - 07DA 20 20 20 20 20 20 1325 .asciz " " - 20 20 20 20 20 00 - 07E6 00 00 00 00 1326 .DB 0,0,0,0 - 1327 - 07EA 20 20 20 20 20 20 1328 .asciz " " - 20 20 20 20 20 00 - 07F6 00 00 00 00 1329 .DB 0,0,0,0 - 1330 - 07FA 00 1331 RTNCODE:.DB 0 ; STATUS RETURNED FROM BDOS CALL. - 07FB 00 1332 CDRIVE: .DB 0 ; CURRENTLY ACTIVE DRIVE. - 07FC 00 1333 CHGDRV: .DB 0 ; CHANGE IN DRIVES FLAG (0=NO CHANGE). - 07FD 00 00 1334 NBYTES: .DW 0 ; BYTE COUNTER USED BY TYPE. - 1335 - 1336 ;dwg; .IF ENDFIL - 1337 ;dwg; .ORG CCPO+07FFH - 1338 ;dwg; .DB 055H - 1339 ;dwg; .ENDIF - 1340 ;dwg; .END - 1341 - 1342 - 07FF 1343 _ccp_end:: - 1344 .area _CODE - 1345 .area _CABS diff --git a/doug/src/ccpb03.rel b/doug/src/ccpb03.rel deleted file mode 100755 index ef0c91b2..00000000 --- a/doug/src/ccpb03.rel +++ /dev/null @@ -1,368 +0,0 @@ -XL -H 8 areas 4 global symbols -M ccpb03 -O -mz80 -S .__.ABS. Def0000 -A _CODE size 0 flags 0 addr 0 -A _DATA size 0 flags 0 addr 0 -A _OVERLAY size 0 flags 0 addr 0 -A _HOME size 0 flags 0 addr 0 -A _GSINIT size 0 flags 0 addr 0 -A _GSFINAL size 0 flags 0 addr 0 -A _CCPB03 size 7FF flags 0 addr 0 -S _ccp Def0000 -S _ccp_start Def0000 -S _ccp_end Def07FF -A _CABS size 0 flags 0 addr 0 -T 00 00 -R 00 00 06 00 -T 00 00 -R 00 00 06 00 -T 00 00 C3 54 03 C3 50 03 7F 00 43 4F 50 59 52 49 -R 00 00 06 00 00 03 06 00 00 06 06 00 -T 0E 00 47 48 54 20 31 39 37 39 20 28 43 29 20 42 -R 00 00 06 00 -T 1C 00 59 20 44 49 47 49 54 41 4C 20 52 45 53 45 -R 00 00 06 00 -T 2A 00 41 52 43 48 20 20 20 20 20 20 00 00 00 00 -R 00 00 06 00 -T 38 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -R 00 00 06 00 -T 46 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -R 00 00 06 00 -T 54 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -R 00 00 06 00 -T 62 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -R 00 00 06 00 -T 70 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -R 00 00 06 00 -T 7E 00 00 00 00 00 00 00 00 00 08 00 00 00 5F 0E -R 00 00 06 00 00 0A 06 00 -T 8C 00 02 C3 05 00 C5 CD 8A 00 C1 C9 3E 0D CD -R 00 00 06 00 00 08 06 00 -T 99 00 90 00 3E 0A C3 90 00 3E 20 C3 90 00 C5 CD -R 00 00 06 00 00 02 06 00 00 07 06 00 00 0C 06 00 -T A7 00 96 00 E1 7E B7 C8 23 E5 CD 8A 00 E1 C3 -R 00 00 06 00 00 02 06 00 00 0B 06 00 -T B4 00 AA 00 0E 0D C3 05 00 5F 0E 0E C3 05 00 CD -R 00 00 06 00 00 02 06 00 -T C2 00 05 00 32 FA 07 3C C9 0E 0F C3 C1 00 AF 32 -R 00 00 06 00 00 05 06 00 00 0C 06 00 -T D0 00 F9 07 11 D9 07 C3 C9 00 0E 10 C3 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T DB 00 C1 00 0E 11 C3 C1 00 0E 12 C3 C1 00 11 -R 00 00 06 00 00 02 06 00 00 07 06 00 00 0C 06 00 -T E8 00 D9 07 C3 DD 00 0E 13 C3 05 00 CD 05 00 B7 -R 00 00 06 00 00 02 06 00 00 05 06 00 -T F6 00 C9 0E 14 C3 F2 00 11 D9 07 C3 F7 00 0E 15 -R 00 00 06 00 00 06 06 00 00 09 06 00 00 0C 06 00 -T 04 01 C3 F2 00 0E 16 C3 C1 00 0E 17 C3 05 00 1E -R 00 00 06 00 00 03 06 00 00 08 06 00 -T 12 01 FF -R 00 00 06 00 -T 13 01 -R 00 00 06 00 -T 13 01 0E 20 C3 05 00 CD 11 01 87 87 87 87 21 -R 00 00 06 00 00 08 06 00 -T 20 01 FB 07 B6 32 04 00 C9 3A FB 07 32 04 00 C9 -R 00 00 06 00 00 02 06 00 00 0A 06 00 -T 2E 01 FE 41 D8 FE 7B D0 E6 5F C9 3A B7 07 B7 CA -R 00 00 06 00 00 0C 06 00 -T 3C 01 94 01 3A FB 07 B7 3E 00 C4 BB 00 11 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 0B 06 00 -T 48 01 B8 07 CD C9 00 CA 94 01 3A -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 51 01 C7 07 3D 32 D8 07 11 B8 07 CD -R 00 00 06 00 00 02 06 00 00 06 06 00 00 09 06 00 -T 5B 01 F7 00 C2 94 01 11 07 00 21 80 00 06 80 CD -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 69 01 38 04 21 C6 07 36 00 23 35 11 B8 07 CD -R 00 00 06 00 00 02 06 00 00 05 06 00 00 0C 06 00 -T 76 01 D8 00 CA 94 01 3A FB 07 B7 C4 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 80 01 BB 00 21 08 00 CD AA 00 CD -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 89 01 C0 01 CA A5 01 CD DB 01 C3 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 92 01 7A 03 CD DB 01 CD 18 01 0E 0A 11 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 9D 01 06 00 CD 05 00 CD 27 01 21 07 00 46 23 78 -R 00 00 06 00 00 02 06 00 00 08 06 00 00 0B 06 00 -T AB 01 B7 CA B8 01 7E CD 2E 01 77 05 C3 A9 01 77 -R 00 00 06 00 00 04 06 00 00 08 06 00 00 0D 06 00 -T B9 01 21 08 00 22 86 00 C9 0E 0B CD 05 00 B7 C8 -R 00 00 06 00 00 03 06 00 00 06 06 00 -T C7 01 0E 01 CD 05 00 B7 C9 0E 19 C3 05 00 11 -R 00 00 06 00 -T D4 01 80 00 0E 1A C3 05 00 -R 00 00 06 00 -T DB 01 -R 00 00 06 00 -T DB 01 21 B7 07 7E B7 C8 36 00 AF CD BB 00 11 -R 00 00 06 00 00 03 06 00 00 0C 06 00 -T E8 01 B8 07 CD ED 00 3A FB 07 C3 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T F1 01 BB 00 CD 96 00 2A 88 00 7E FE 20 CA -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T FD 01 0C 02 B7 CA 0C 02 E5 CD 8A 00 E1 23 C3 -R 00 00 06 00 00 02 06 00 00 06 06 00 00 0A 06 00 -T 0A 02 F9 01 3E 3F CD 8A 00 CD 96 00 CD -R 00 00 06 00 00 02 06 00 00 07 06 00 00 0A 06 00 -T 15 02 DB 01 C3 7A 03 1A B7 C8 FE 20 DA F3 01 C8 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 0D 06 00 -T 23 02 FE 3D C8 FE 5F C8 FE 2E C8 FE 3A C8 FE 3B -R 00 00 06 00 -T 31 02 C8 FE 3C C8 FE 3E C8 C9 -R 00 00 06 00 -T 39 02 -R 00 00 06 00 -T 39 02 1A B7 C8 FE 20 C0 13 C3 39 02 85 6F D0 24 -R 00 00 06 00 00 0A 06 00 -T 47 02 C9 3E 00 21 D9 07 CD 43 02 E5 E5 AF 32 -R 00 00 06 00 00 06 06 00 00 09 06 00 -T 54 02 FC 07 2A 86 00 EB CD 39 02 EB 22 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 09 06 00 -T 5F 02 88 00 EB E1 1A B7 CA 73 02 DE 40 47 13 1A -R 00 00 06 00 00 02 06 00 00 09 06 00 -T 6D 02 FE 3A CA 7A 02 1B 3A FB 07 77 C3 80 02 78 -R 00 00 06 00 00 05 06 00 00 09 06 00 00 0D 06 00 -T 7B 02 32 FC 07 70 13 06 08 CD 1A 02 CA A3 02 23 -R 00 00 06 00 00 03 06 00 00 0A 06 00 00 0D 06 00 -T 89 02 FE 2A C2 93 02 36 3F C3 95 02 77 13 05 C2 -R 00 00 06 00 00 05 06 00 00 0A 06 00 -T 97 02 82 02 CD 1A 02 CA AA 02 13 C3 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T A1 02 99 02 23 36 20 05 C2 A3 02 06 03 FE 2E C2 -R 00 00 06 00 00 02 06 00 00 09 06 00 -T AF 02 D3 02 13 CD 1A 02 CA D3 02 23 FE 2A C2 -R 00 00 06 00 00 02 06 00 00 06 06 00 00 09 06 00 -T BC 02 C3 02 36 3F C3 C5 02 77 13 05 C2 B2 02 CD -R 00 00 06 00 00 02 06 00 00 07 06 00 00 0D 06 00 -T CA 02 1A 02 CA DA 02 13 C3 C9 02 23 36 20 05 C2 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 09 06 00 -T D8 02 D3 02 06 03 23 36 00 05 C2 DC 02 EB 22 -R 00 00 06 00 00 02 06 00 00 0B 06 00 -T E5 02 86 00 E1 01 0B 00 23 7E FE 3F C2 F3 02 04 -R 00 00 06 00 00 02 06 00 00 0D 06 00 -T F3 02 0D C2 EB 02 78 B7 C9 44 49 52 20 45 52 41 -R 00 00 06 00 00 04 06 00 -T 01 03 20 54 59 50 45 53 41 56 45 52 45 4E 20 55 -R 00 00 06 00 -T 0F 03 53 45 52 4D 4F 4E 20 70 04 18 05 56 05 -R 00 00 06 00 00 09 06 00 00 0B 06 00 00 0D 06 00 -T 1C 03 A6 05 09 06 87 06 -R 00 00 06 00 00 02 06 00 00 04 06 00 00 06 06 00 -T 22 03 6D 04 9E 06 21 FA 02 0E 00 79 FE 07 D0 11 -R 00 00 06 00 00 02 06 00 00 04 06 00 00 07 06 00 -T 30 03 DA 07 06 04 1A BE C2 47 03 13 23 05 C2 -R 00 00 06 00 00 02 06 00 00 09 06 00 -T 3D 03 34 03 1A FE 20 C2 4C 03 79 C9 23 05 C2 -R 00 00 06 00 00 02 06 00 00 08 06 00 -T 4A 03 47 03 0C C3 2B 03 -R 00 00 06 00 00 02 06 00 00 06 06 00 -T 50 03 -R 00 00 06 00 -T 50 03 AF 32 07 00 31 B7 07 C5 79 1F 1F 1F 1F E6 -R 00 00 06 00 00 04 06 00 00 07 06 00 -T 5E 03 0F 5F CD 13 01 CD B6 00 32 B7 07 C1 79 E6 -R 00 00 06 00 00 05 06 00 00 08 06 00 00 0B 06 00 -T 6C 03 0F 32 FB 07 CD BB 00 3A 07 00 B7 C2 -R 00 00 06 00 00 04 06 00 00 07 06 00 00 0A 06 00 -T 78 03 A6 03 31 B7 07 CD 96 00 CD -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 81 03 CE 01 C6 41 CD 8A 00 CD 11 01 FE 0A 38 0A -R 00 00 06 00 00 02 06 00 00 07 06 00 00 0A 06 00 -T 8F 03 3E 31 CD 8A 00 CD 11 01 D6 0A C6 30 CD -R 00 00 06 00 00 05 06 00 00 08 06 00 -T 9C 03 8A 00 3E 3E CD 8A 00 CD 37 01 11 80 00 CD -R 00 00 06 00 00 02 06 00 00 07 06 00 00 0A 06 00 -T AA 03 D6 01 CD CE 01 32 FB 07 CD -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T B3 03 48 02 C4 F3 01 3A FC 07 B7 C2 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T BD 03 9E 06 CD 26 03 21 16 03 5F 16 00 19 19 7E -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T CB 03 23 66 6F E9 01 D5 03 C3 A5 00 52 65 61 64 -R 00 00 06 00 00 07 06 00 00 0A 06 00 -T D9 03 20 45 72 72 6F 72 00 01 E6 03 C3 A5 00 4E -R 00 00 06 00 00 0A 06 00 00 0D 06 00 -T E7 03 6F 20 46 69 6C 65 00 CD 48 02 3A FC 07 B7 -R 00 00 06 00 00 0A 06 00 00 0D 06 00 -T F5 03 C2 F3 01 21 DA 07 01 0B 00 7E FE 20 CA -R 00 00 06 00 00 03 06 00 00 06 06 00 -T 02 04 29 04 23 D6 30 FE 0A D2 F3 01 57 78 E6 E0 -R 00 00 06 00 00 02 06 00 00 0A 06 00 -T 10 04 C2 F3 01 78 07 07 07 80 DA F3 01 80 DA -R 00 00 06 00 00 03 06 00 00 0B 06 00 -T 1D 04 F3 01 82 DA F3 01 47 0D C2 FE 03 C9 7E FE -R 00 00 06 00 00 02 06 00 00 06 06 00 00 0B 06 00 -T 2B 04 20 C2 F3 01 23 0D C2 29 04 78 C9 06 03 7E -R 00 00 06 00 00 04 06 00 00 09 06 00 -T 39 04 12 23 13 05 C2 38 04 C9 21 80 00 81 CD -R 00 00 06 00 00 07 06 00 -T 46 04 43 02 7E C9 AF 32 D9 07 3A FC 07 B7 C8 3D -R 00 00 06 00 00 02 06 00 00 08 06 00 00 0B 06 00 -T 54 04 21 FB 07 BE C8 C3 BB 00 3A FC 07 B7 C8 3D -R 00 00 06 00 00 03 06 00 00 08 06 00 00 0B 06 00 -T 62 04 21 FB 07 BE C8 3A FB 07 C3 BB 00 C3 00 FC -R 00 00 06 00 00 03 06 00 00 08 06 00 00 0B 06 00 -T 70 04 CD 48 02 CD 4A 04 21 DA 07 7E FE 20 C2 -R 00 00 06 00 00 03 06 00 00 06 06 00 00 09 06 00 -T 7D 04 88 04 06 0B 36 3F 23 05 C2 81 04 1E 00 D5 -R 00 00 06 00 00 02 06 00 00 0B 06 00 -T 8B 04 CD E7 00 CC E0 03 CA 14 05 3A -R 00 00 06 00 00 03 06 00 00 06 06 00 00 09 06 00 -T 95 04 FA 07 0F 0F 0F E6 60 4F 3E 0A CD 41 04 17 -R 00 00 06 00 00 02 06 00 00 0D 06 00 -T A3 04 DA 08 05 D1 7B 1C D5 E6 03 F5 C2 C5 04 CD -R 00 00 06 00 00 03 06 00 00 0D 06 00 -T B1 04 96 00 C5 CD CE 01 C1 C6 41 CD 90 00 3E 3A -R 00 00 06 00 00 02 06 00 00 06 06 00 00 0C 06 00 -T BF 04 CD 90 00 C3 CD 04 CD A0 00 3E 3A CD -R 00 00 06 00 00 03 06 00 00 06 06 00 00 09 06 00 -T CB 04 90 00 CD A0 00 06 01 78 CD 41 04 E6 7F FE -R 00 00 06 00 00 02 06 00 00 05 06 00 00 0B 06 00 -T D9 04 20 C2 F2 04 F1 F5 FE 03 C2 F0 04 3E 09 CD -R 00 00 06 00 00 04 06 00 00 0B 06 00 -T E7 04 41 04 E6 7F FE 20 CA 07 05 3E 20 CD 90 00 -R 00 00 06 00 00 02 06 00 00 09 06 00 00 0E 06 00 -T F5 04 04 78 FE 0C D2 07 05 FE 09 C2 D2 04 CD -R 00 00 06 00 00 07 06 00 00 0C 06 00 -T 02 05 A0 00 C3 D2 04 F1 CD C0 01 C2 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 09 06 00 -T 0C 05 14 05 CD E2 00 C3 91 04 D1 C3 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 16 05 92 07 CD 48 02 FE 0B C2 3B 05 01 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 0A 06 00 -T 21 05 4B 05 CD A5 00 CD 37 01 21 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 2A 05 07 00 35 C2 7A 03 23 7E FE 59 C2 7A 03 23 -R 00 00 06 00 00 02 06 00 00 06 06 00 00 0D 06 00 -T 38 05 22 86 00 CD 4A 04 11 D9 07 CD -R 00 00 06 00 00 03 06 00 00 06 06 00 00 09 06 00 -T 42 05 ED 00 3C CC E0 03 C3 92 07 41 6C 6C 20 28 -R 00 00 06 00 00 02 06 00 00 06 06 00 00 09 06 00 -T 50 05 59 2F 4E 29 3F 00 CD 48 02 C2 F3 01 CD -R 00 00 06 00 00 09 06 00 00 0C 06 00 -T 5D 05 4A 04 CD CE 00 CA A0 05 CD -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 66 05 96 00 21 FD 07 36 FF 21 FD 07 7E FE 80 DA -R 00 00 06 00 00 02 06 00 00 05 06 00 00 0A 06 00 -T 74 05 80 05 E5 CD FC 00 E1 C2 99 05 AF 77 34 21 -R 00 00 06 00 00 02 06 00 00 06 06 00 00 0A 06 00 -T 82 05 80 00 CD 43 02 7E FE 1A CA 92 07 CD 8A 00 -R 00 00 06 00 00 05 06 00 00 0B 06 00 00 0E 06 00 -T 90 05 CD C0 01 C2 92 07 C3 6D 05 3D CA -R 00 00 06 00 00 03 06 00 00 06 06 00 00 09 06 00 -T 9B 05 92 07 CD CF 03 CD 5C 04 C3 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T A4 05 F3 01 CD EE 03 F5 CD 48 02 C2 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 09 06 00 -T AE 05 F3 01 CD 4A 04 11 D9 07 D5 CD -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T B8 05 ED 00 D1 CD 07 01 CA F4 05 AF 32 -R 00 00 06 00 00 02 06 00 00 06 06 00 00 09 06 00 -T C3 05 F9 07 F1 6F 26 00 29 11 00 01 7C B5 CA -R 00 00 06 00 00 02 06 00 -T D0 05 EA 05 2B E5 21 80 00 19 E5 CD D6 01 11 -R 00 00 06 00 00 02 06 00 00 0C 06 00 -T DD 05 D9 07 CD 02 01 D1 E1 C2 F4 05 C3 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 0A 06 00 -T E8 05 CD 05 11 D9 07 CD D8 00 3C C2 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T F2 05 FA 05 01 00 06 CD A5 00 CD -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T FB 05 D3 01 C3 92 07 4E 6F 20 53 70 61 63 65 00 -R 00 00 06 00 00 02 06 00 00 05 06 00 -T 09 06 CD 48 02 C2 F3 01 3A FC 07 F5 CD -R 00 00 06 00 00 03 06 00 00 06 06 00 00 09 06 00 -T 14 06 4A 04 CD E7 00 C2 72 06 21 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 1D 06 D9 07 11 E9 07 06 10 CD 38 04 2A -R 00 00 06 00 00 02 06 00 00 05 06 00 00 0A 06 00 -T 28 06 86 00 EB CD 39 02 FE 3D CA 38 06 FE 20 C2 -R 00 00 06 00 00 02 06 00 00 06 06 00 00 0B 06 00 -T 36 06 6C 06 EB 23 22 86 00 CD 48 02 C2 -R 00 00 06 00 00 02 06 00 00 07 06 00 00 0A 06 00 -T 41 06 6C 06 F1 47 21 FC 07 7E B7 CA 52 06 B8 70 -R 00 00 06 00 00 02 06 00 00 07 06 00 00 0C 06 00 -T 4F 06 C2 6C 06 70 AF 32 D9 07 CD E7 00 CA -R 00 00 06 00 00 03 06 00 00 08 06 00 00 0B 06 00 -T 5B 06 66 06 11 D9 07 CD 0C 01 C3 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 64 06 92 07 CD E0 03 C3 92 07 CD -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 6D 06 5C 04 C3 F3 01 01 7B 06 CD -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 76 06 A5 00 C3 92 07 46 69 6C 65 20 45 78 69 73 -R 00 00 06 00 00 02 06 00 00 05 06 00 -T 84 06 74 73 00 CD EE 03 FE 10 D2 F3 01 5F 3A -R 00 00 06 00 00 06 06 00 00 0B 06 00 -T 91 06 DA 07 FE 20 CA F3 01 CD 13 01 C3 -R 00 00 06 00 00 02 06 00 00 07 06 00 00 0A 06 00 -T 9C 06 95 07 3A DA 07 FE 20 C2 BA 06 3A -R 00 00 06 00 00 02 06 00 00 05 06 00 00 0A 06 00 -T A7 06 FC 07 B7 CA 95 07 3D 32 FB 07 CD -R 00 00 06 00 00 02 06 00 00 06 06 00 00 0A 06 00 -T B2 06 27 01 CD BB 00 C3 95 07 11 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T BB 06 E2 07 1A FE 20 C2 F3 01 D5 CD 4A 04 D1 21 -R 00 00 06 00 00 02 06 00 00 08 06 00 00 0C 06 00 -T C9 06 8F 07 CD 36 04 CD CE 00 C2 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T D2 06 EA 06 1E 00 CD 13 01 CD CE 00 C2 -R 00 00 06 00 00 02 06 00 00 07 06 00 00 0A 06 00 -T DD 06 EA 06 21 D9 07 36 02 CD CE 00 CA -R 00 00 06 00 00 02 06 00 00 05 06 00 00 0A 06 00 -T E8 06 77 07 21 00 01 E5 EB CD D6 01 11 D9 07 CD -R 00 00 06 00 00 02 06 00 00 0A 06 00 00 0D 06 00 -T F6 06 F7 00 C2 0D 07 E1 11 80 00 19 11 00 00 7D -R 00 00 06 00 00 02 06 00 00 05 06 00 00 0D 06 00 -T 04 07 93 7C 9A D2 7D 07 C3 ED 06 E1 3D C2 7D 07 -R 00 00 06 00 00 06 06 00 00 09 06 00 00 0E 06 00 -T 12 07 CD 5C 04 CD 48 02 21 FC 07 E5 7E 32 -R 00 00 06 00 00 03 06 00 00 06 06 00 00 09 06 00 -T 1E 07 D9 07 3E 10 CD 4A 02 E1 7E 32 E9 07 AF 32 -R 00 00 06 00 00 02 06 00 00 07 06 00 00 0C 06 00 -T 2C 07 F9 07 11 5C 00 21 D9 07 06 21 CD 38 04 21 -R 00 00 06 00 00 02 06 00 00 08 06 00 00 0D 06 00 -T 3A 07 08 00 7E B7 CA 4A 07 FE 20 CA 4A 07 23 C3 -R 00 00 06 00 00 02 06 00 00 07 06 00 00 0C 06 00 -T 48 07 3C 07 06 00 11 81 00 7E 12 B7 CA 5B 07 04 -R 00 00 06 00 00 02 06 00 00 0D 06 00 -T 56 07 23 13 C3 4F 07 78 32 80 00 CD 96 00 CD -R 00 00 06 00 00 05 06 00 00 0C 06 00 -T 63 07 D3 01 CD 18 01 CD 00 01 31 B7 07 CD -R 00 00 06 00 00 02 06 00 00 05 06 00 00 0B 06 00 -T 6F 07 27 01 CD BB 00 C3 7A 03 CD -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 78 07 5C 04 C3 F3 01 01 86 07 CD -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 81 07 A5 00 C3 92 07 42 61 64 20 4C 6F 61 64 00 -R 00 00 06 00 00 02 06 00 00 05 06 00 -T 8F 07 43 4F 4D CD 5C 04 -R 00 00 06 00 00 06 06 00 -T 95 07 -R 00 00 06 00 -T 95 07 CD 48 02 3A DA 07 D6 20 21 FC 07 B6 C2 -R 00 00 06 00 00 03 06 00 00 06 06 00 00 0B 06 00 -T A2 07 F3 01 C3 7A 03 00 00 00 00 00 00 00 00 00 -R 00 00 06 00 00 02 06 00 00 05 06 00 -T B0 07 00 00 00 00 00 00 00 -R 00 00 06 00 -T B7 07 -R 00 00 06 00 -T B7 07 00 00 24 24 24 20 20 20 20 20 53 55 42 00 -R 00 00 06 00 -T C5 07 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -R 00 00 06 00 -T D3 07 00 00 00 00 00 00 00 20 20 20 20 20 20 20 -R 00 00 06 00 -T E1 07 20 20 20 20 00 00 00 00 00 20 20 20 20 20 -R 00 00 06 00 -T EF 07 20 20 20 20 20 20 00 00 00 00 00 00 00 00 -R 00 00 06 00 -T FD 07 00 00 -R 00 00 06 00 -T FF 07 -R 00 00 06 00 diff --git a/doug/src/ccpb03.s b/doug/src/ccpb03.s deleted file mode 100755 index 67ddec45..00000000 --- a/doug/src/ccpb03.s +++ /dev/null @@ -1,1345 +0,0 @@ - .title ccpb03.s derived from ccpb03.asm - .sbttl by Douglas Goodall 5/16/2011 dwg - - .module ccpb03 - .optsdcc -mz80 - -;-------------------------------------------------------- -; Public variables in this module -;-------------------------------------------------------- - .globl _ccp -;-------------------------------------------------------- -; special function registers -;-------------------------------------------------------- -;-------------------------------------------------------- -; ram data -;-------------------------------------------------------- - .area _DATA -;-------------------------------------------------------- -; overlayable items in ram -;-------------------------------------------------------- - .area _OVERLAY -;-------------------------------------------------------- -; external initialized ram data -;-------------------------------------------------------- -;-------------------------------------------------------- -; global & static initialisations -;-------------------------------------------------------- - .area _HOME - .area _GSINIT - .area _GSFINAL - .area _GSINIT -;-------------------------------------------------------- -; Home -;-------------------------------------------------------- - .area _HOME - .area _HOME -;-------------------------------------------------------- -; code -;-------------------------------------------------------- - -; .area _CODE - .area _CCPB03 - -_ccp_start:: -_ccp: - -MON = 1 ;ADD THE CCP MON COMMAND -USRDSP = 1 ;SHOW THE USER NUMBER -CHKU0B = 1 ;CHECK FOR TRANSIENTS ON USER 0 TOO -ENDFIL = 1 ;FILE FULL CCP SIZE -; -;************************************************************** -;* -;* C C P - C O N S O L E C O M M A N D P R O C E S S O R -;* -;************************************************************** -;* -IOBYTE = 3 ; I/O DEFINITION BYTE. -TDRIVE = 4 ; CURRENT DRIVE NAME AND USER NUMBER. -ENTRY = 5 ; ENTRY POINT FOR THE CP/M BDOS. -TFCB = 0x5C ; DEFAULT FILE CONTROL BLOCK. -TBUFF = 0x80 ; I/O BUFFER AND COMMAND LINE STORAGE. -TBASE = 0x0100 ; TRANSIANT PROGRAM STORAGE AREA. -MONADR = 0x0FC00 ;MONITOR PROGRAM -; -; SET CONTROL CHARACTER .EQUATES. -; -CNTRLC = 0x03 ; CONTROL-C -CNTRLE = 0x05 ; CONTROL-E -BS = 0x08 ; BACKSPACE -TAB = 0x09 ; TAB -LF = 0x0A ; LINE FEED -FF = 0x0C ; FORM FEED -CR = 0x0D ; CARRIAGE RETURN -CNTRLP = 0x10 ; CONTROL-P -CNTRLR = 0x12 ; CONTROL-R -CNTRLS = 0x13 ; CONTROL-S -CNTRLU = 0x15 ; CONTROL-U -CNTRLX = 0x18 ; CONTROL-X -CNTRLZ = 0x1A ; CONTROL-Z (END-OF-FILE MARK) -ASTERICK = 0x2A -COLON = 0x3A -LESSTHAN = 0x3C -ASCSPACE = 0x20 ; SPACE -PERIOD = 0x2e ; PERIOD -EQUAL = 0x3D -GREATERTHAN = 0x3E -QUESTION = 0x3F ;QUESTION MARK -UNDERSCORE = 0x5F -LCURLY = 0x7B ; { -DEL = 0x7F ; RUBOUT -; -; SET ORIGIN FOR CP/M -; - -NK = 59 ;SYSTEM SIZE -BASE = (NK*1024)-0x5000 -CCPO = BASE+0x3400 ;CCP ORIGIN -BDOSO = BASE+0x3C00 ;BDOS ORIGIN -BIOSO = BASE+0x4A00 ;BIOS ORIGIN - -;dwg; .ORG CCPO -; -CBASE: JP COMMAND ; EXECUTE COMMAND PROCESSOR (CCP). - JP CLEARBUF ; ENTRY TO EMPTY INPUT BUFFER BEFORE STARTING CCP. - -; -; STANDARD CP/M CCP INPUT BUFFER. FORMAT IS (MAX LENGTH), -; (ACTUAL LENGTH), (CHAR #1), (CHAR #2), (CHAR #3), ETC. -; -INBUFF: .DB 127 ; LENGTH OF INPUT BUFFER. - -; N8VEM - if add any text after this point, change .DB 0 below to length -; and put a 0 after the text, and delete the same number of zeros after the dig -; so that inpoint ends up at the same spot -; INBUFF+1 is cleared on the next warm boot, so only runs once. - .DB 0 ;CURRENT LENGTH OF CONTENTS. - - -; .DB 17 ; Autoboot length of string -; .DB "SUPERSUB AUTOEXEC" -; .DB 0 ; zero at end - - - .ascii "COPYRIGHT" - .ascii " 1979 (C) BY " - .ascii "DIGITAL RESEARCH " - .ascii " " - -;dwg; .ORG INBUFF+128 -;dwg; becausje org's are not allowed in rel areas, it has been -; replaced with the following array of .db's to achieve the -; same purpose - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0 - -;; s/b d086 here - -INPOINT:.DW INBUFF+2 ; INPUT LINE POINTER -NAMEPNT:.DW 0 ; INPUT LINE POINTER USED FOR ERROR MESSAGE. POINTS TO -; ;START OF NAME IN ERROR. -; -; ROUTINE TO PRINT (A) ON THE CONSOLE. ALL REGISTERS USED. -; -PRINT: LD E,A ; SETUP BDOS CALL. - LD C,#2 - JP ENTRY -; -; ROUTINE TO PRINT (A) ON THE CONSOLE AND TO SAVE (BC). -; -PRINTB: PUSH BC - CALL PRINT - POP BC - RET -; -; ROUTINE TO SEND A CARRIAGE RETURN, LINE FEED COMBINATION -; TO THE CONSOLE. -; -CRLF: LD A,#CR - CALL PRINTB - LD A,#LF - JP PRINTB -; -; ROUTINE TO SEND ONE SPACE TO THE CONSOLE AND SAVE (BC). -; -SPACE: LD A,#ASCSPACE - JP PRINTB -; -; ROUTINE TO PRINT CHARACTER STRING POINTED TO BE (BC) ON THE -; CONSOLE. IT MUST TERMINATE WITH A NULL BYTE. -; -PLINE: PUSH BC - CALL #CRLF - POP HL -PLINE2: LD A,(HL) - OR A - RET Z - INC HL - PUSH HL - CALL PRINT - POP HL - JP PLINE2 -; -; ROUTINE TO RESET THE DISK SYSTEM. -; -RESDSK: LD C,#13 - JP ENTRY -; -; ROUTINE TO SELECT DISK (A). -; -DSKSEL: LD E,A - LD C,#14 - JP ENTRY -; -; ROUTINE TO CALL BDOS AND SAVE THE RETURN CODE. THE ZERO -; FLAG IS SET ON A RETURN OF 0FFH. -; -ENTRY1: CALL ENTRY - LD (RTNCODE),A ; SAVE RETURN CODE. - INC A ; SET ZERO IF 0FFH RETURNED. - RET -; -; ROUTINE TO OPEN A FILE. (DE) MUST POINT TO THE FCB. -; -OPEN: LD C,#15 - JP ENTRY1 -; -; ROUTINE TO OPEN FILE AT (FCB). -; -OPENFCB:XOR A ; CLEAR THE RECORD NUMBER BYTE AT FCB+32 - LD (FCB+32),A - LD DE,#FCB - JP OPEN -; -; ROUTINE TO CLOSE A FILE. (DE) POINTS TO FCB. -; -CLOSE: LD C,#16 - JP ENTRY1 -; -; ROUTINE TO SEARCH FOR THE FIRST FILE WITH AMBIGUEOUS NAME -; (DE). -; -SRCHFST:LD C,#17 - JP ENTRY1 -; -; SEARCH FOR THE NEXT AMBIGEOUS FILE NAME. -; -SRCHNXT:LD C,#18 - JP ENTRY1 -; -; SEARCH FOR FILE AT (FCB). -; -SRCHFCB:LD DE,#FCB - JP SRCHFST -; -; ROUTINE TO DELETE A FILE POINTED TO BY (DE). -; -DELETE: LD C,#19 - JP ENTRY -; -; ROUTINE TO CALL THE BDOS AND SET THE ZERO FLAG IF A ZERO -; STATUS IS RETURNED. -; -ENTRY2: CALL ENTRY - OR A ; SET ZERO FLAG IF APPROPRIATE. - RET -; -; ROUTINE TO READ THE NEXT RECORD FROM A S.EQUENTIAL FILE. -; (DE) POINTS TO THE FCB. -; -RDREC: LD C,#20 - JP ENTRY2 -; -; ROUTINE TO READ FILE AT (FCB). -; -READFCB:LD DE,#FCB - JP RDREC -; -; ROUTINE TO WRITE THE NEXT RECORD OF A S.EQUENTIAL FILE. -; (DE) POINTS TO THE FCB. -; -WRTREC: LD C,#21 - JP ENTRY2 -; -; ROUTINE TO CREATE THE FILE POINTED TO BY (DE). -; -CREATE: LD C,#22 - JP ENTRY1 -; -; ROUTINE TO RENAME THE FILE POINTED TO BY (DE). NOTE THAT -; THE NEW NAME STARTS AT (DE+16). -; -RENAM: LD C,#23 - JP ENTRY -; -; GET THE CURRENT USER CODE. -; -GETUSR: LD E,#0x0FF -; -; ROUTNE TO GET OR SET THE CURRENT USER CODE. -; IF (E) IS FF THEN THIS IS A GET, ELSE IT IS A SET. -; -GETSETUC: - LD C,#32 - JP ENTRY -; -; ROUTINE TO SET THE CURRENT DRIVE BYTE AT (TDRIVE). -; -SETCDRV:CALL GETUSR ; GET USER NUMBER - ADD A,A ; AND SHIFT INTO THE UPPER 4 BITS. - ADD A,A - ADD A,A - ADD A,A - LD HL,#CDRIVE ; NOW ADD IN THE CURRENT DRIVE NUMBER. - OR (HL) - LD (TDRIVE),A ; AND SAVE. - RET -; -; MOVE CURRENTLY ACTIVE DRIVE DOWN TO (TDRIVE). -; -MOVECD: LD A,(CDRIVE) - LD (TDRIVE),A - RET -; -; ROUTINE TO CONVERT (A) INTO UPPER CASE ASCII. ONLY LETTERS -; ARE AFFECTED. -; -UPPER: CP #0x41 ; CHECK FOR LETTERS IN THE RANGE OF 'A' TO 'Z'. - RET C - CP #LCURLY - RET NC - AND #0x5F ; CONVERT IT IF FOUND. - RET -; -; ROUTINE TO GET A LINE OF INPUT. WE MUST CHECK TO SEE IF THE -; USER IS IN (BATCH) MODE. IF SO, THEN READ THE INPUT FROM FILE -; ($$$.SUB). AT THE END, RESET TO CONSOLE INPUT. -; -GETINP: LD A,(BATCH) ; IF =0, THEN USE CONSOLE INPUT. - OR A - JP Z,GETINP1 -; -; USE THE SUBMIT FILE ($$$.SUB) WHICH IS PREPARED BY A -; SUBMIT RUN. IT MUST BE ON DRIVE (A) AND IT WILL BE DELETED -; IF AND ERROR OCCURES (LIKE EOF). -; - LD A,(CDRIVE) ; SELECT DRIVE 0 IF NEED BE. - OR A - LD A,#0 ; ALWAYS USE DRIVE A FOR SUBMIT. - CALL NZ,DSKSEL ; SELECT IT IF R.EQUIRED. - LD DE,#BATCHFCB - CALL OPEN ; LOOK FOR IT. - JP Z,GETINP1 ; IF NOT THERE, USE NORMAL INPUT. - LD A,(BATCHFCB+15) ; GET LAST RECORD NUMBER+1. - DEC A - LD (BATCHFCB+32),A - LD DE,#BATCHFCB - CALL RDREC ; READ LAST RECORD. - JP NZ,GETINP1 ; QUIT ON END OF FILE. -; -; MOVE THIS RECORD INTO INPUT BUFFER. -; - LD DE,#INBUFF+1 - LD HL,#TBUFF ; DATA WAS READ INTO BUFFER HERE. - LD B,#128 ; ALL 128 CHARACTERS MAY BE USED. - CALL HL2DE ; (HL) TO (DE), (B) BYTES. - LD HL,#BATCHFCB+14 - LD (HL),#0 ; ZERO OUT THE 'S2' BYTE. - INC HL ; AND DECREMENT THE RECORD COUNT. - DEC (HL) - LD DE,#BATCHFCB ; CLOSE THE BATCH FILE NOW. - CALL CLOSE - JP Z,GETINP1 ; QUIT ON AN ERROR. - LD A,(CDRIVE) ; RE-SELECT PREVIOUS DRIVE IF NEED BE. - OR A - CALL NZ,DSKSEL ; DON'T DO NEEDLESS SELECTS. -; -; PRINT LINE JUST READ ON CONSOLE. -; - LD HL,#INBUFF+2 - CALL PLINE2 - CALL CHKCON ; CHECK CONSOLE, QUIT ON A KEY. - JP Z,GETINP2 ; JUMP IF NO KEY IS PRESSED. -; -; TERMINATE THE SUBMIT JOB ON ANY KEYBOARD INPUT. DELETE THIS -; FILE SUCH THAT IT IS NOT RE-STARTED AND JUMP TO NORMAL KEYBOARD -; INPUT SECTION. -; - CALL DELBATCH ; DELETE THE BATCH FILE. - JP CMMND1 ; AND RESTART COMMAND INPUT. -; -; GET HERE FOR NORMAL KEYBOARD INPUT. DELETE THE SUBMIT FILE -; INCASE THERE WAS ONE. -; -GETINP1:CALL DELBATCH ; DELETE FILE ($$$.SUB). - CALL SETCDRV ; RESET ACTIVE DISK. - LD C,#10 ; GET LINE FROM CONSOLE DEVICE. - LD DE,#INBUFF - CALL ENTRY - CALL MOVECD ; RESET CURRENT DRIVE (AGAIN). -; -; CONVERT INPUT LINE TO UPPER CASE. -; -GETINP2:LD HL,#INBUFF+1 - LD B,(HL) ; (B)=CHARACTER COUNTER. -GETINP3:INC HL - LD A,B ; END OF THE LINE? - OR A - JP Z,GETINP4 - LD A,(HL) ; CONVERT TO UPPER CASE. - CALL UPPER - LD (HL),A - DEC B ; ADJUST CHARACTER COUNT. - JP GETINP3 -GETINP4:LD (HL),A ; ADD TRAILING NULL. - LD HL,#INBUFF+2 - LD (INPOINT),HL ; RESET INPUT LINE POINTER. - RET -; -; ROUTINE TO CHECK THE CONSOLE FOR A KEY PRESSED. THE ZERO -; FLAG IS SET IS NONE, ELSE THE CHARACTER IS RETURNED IN (A). -; -CHKCON: LD C,#11 ; CHECK CONSOLE. - CALL ENTRY - OR A - RET Z ; RETURN IF NOTHING. - LD C,#1 ; ELSE GET CHARACTER. - CALL ENTRY - OR A ; CLEAR ZERO FLAG AND RETURN. - RET -; -; ROUTINE TO GET THE CURRENTLY ACTIVE DRIVE NUMBER. -; -GETDSK: LD C,#25 - JP ENTRY -; -; SET THE STABDARD DMA ADDRESS. -; -STDDMA: LD DE,#TBUFF -; -; ROUTINE TO SET THE DMA ADDRESS TO (DE). -; -DMASET: LD C,#26 - JP ENTRY -; -; DELETE THE BATCH FILE CREATED BY SUBMIT. -; -DELBATCH: - LD HL,#BATCH ; IS BATCH ACTIVE? - LD A,(HL) - OR A - RET Z - LD (HL),#0 ; YES, DE-ACTIVATE IT. - XOR A - CALL DSKSEL ; SELECT DRIVE 0 FOR SURE. - LD DE,#BATCHFCB ; AND DELETE THIS FILE. - CALL DELETE - LD A,(CDRIVE) ; RESET CURRENT DRIVE. - JP DSKSEL -; -; PRINT BACK FILE NAME WITH A '?' TO INDICATE A SYNTAX ERROR. -; -SYNERR: CALL CRLF ; END CURRENT LINE. - LD HL,(NAMEPNT) ; THIS POINTS TO NAME IN ERROR. -SYNERR1:LD A,(HL) ; PRINT IT UNTIL A SPACE OR NULL IS FOUND. - CP #ASCSPACE - JP Z,SYNERR2 - OR A - JP Z,SYNERR2 - PUSH HL - CALL PRINT - POP HL - INC HL - JP SYNERR1 -SYNERR2:LD A,#QUESTION ; ADD TRAILING '?'. - CALL PRINT - CALL CRLF - CALL DELBATCH ; DELETE ANY BATCH FILE. - JP CMMND1 ; AND RESTART FROM CONSOLE INPUT. -; -; CHECK CHARACTER AT (DE) FOR LEGAL COMMAND INPUT. NOTE THAT THE -; ZERO FLAG IS SET IF THE CHARACTER IS A DELIMITER. -; -CHECK: LD A,(DE) - OR A - RET Z - CP #ASCSPACE ; CONTROL CHARACTERS ARE NOT LEGAL HERE. - JP C,SYNERR - RET Z ; CHECK FOR VALID DELIMITER. - CP #EQUAL - RET Z - CP #UNDERSCORE - RET Z - CP #PERIOD - RET Z - CP #COLON - RET Z - CP #0x3b - RET Z - CP #LESSTHAN - RET Z - CP #GREATERTHAN - RET Z - RET -; -; GET THE NEXT NON-BLANK CHARACTER FROM (DE). -; -NONBLANK: - LD A,(DE) - OR A ; STRING ENDS WITH A NULL. - RET Z - CP #ASCSPACE - RET NZ - INC DE - JP NONBLANK -; -; ADD (HL)=(HL)+(A) -; -ADDHL: ADD A,L - LD L,A - RET NC ; TAKE CARE OF ANY CARRY. - INC H - RET -; -; CONVERT THE FIRST NAME IN (FCB). -; -CONVFST:LD A,#0 -; -; FORMAT A FILE NAME (CONVERT * TO '?', ETC.). ON RETURN, -; (A)=0 IS AN UNAMBIGEOUS NAME WAS SPECIFIED. ENTER WITH (A) .EQUAL TO -; THE POSITION WITHIN THE FCB FOR THE NAME (EITHER 0 OR 16). -; -CONVERT:LD HL,#FCB - CALL ADDHL - PUSH HL - PUSH HL - XOR A - LD (CHGDRV),A ; INITIALIZE DRIVE CHANGE FLAG. - LD HL,(INPOINT) ; SET (HL) AS POINTER INTO INPUT LINE. - EX DE,HL - CALL NONBLANK ; GET NEXT NON-BLANK CHARACTER. - EX DE,HL - LD (NAMEPNT),HL ; SAVE POINTER HERE FOR ANY ERROR MESSAGE. - EX DE,HL - POP HL - LD A,(DE) ; GET FIRST CHARACTER. - OR A - JP Z,CONVRT1 - SBC A,#0x41-1 ; MIGHT BE A DRIVE NAME, CONVERT TO BINARY. - LD B,A ; AND SAVE. - INC DE ; CHECK NEXT CHARACTER FOR A ':'. - LD A,(DE) - CP #COLON - JP Z,CONVRT2 - DEC DE ; NOPE, MOVE POINTER BACK TO THE START OF THE LINE. -CONVRT1:LD A,(CDRIVE) - LD (HL),A - JP CONVRT3 -CONVRT2:LD A,B - LD (CHGDRV),A ; SET CHANGE IN DRIVES FLAG. - LD (HL),B - INC DE -; -; CONVERT THE BASIC FILE NAME. -; -CONVRT3:LD B,#8 -CONVRT4:CALL CHECK - JP Z,CONVRT8 - INC HL - CP #ASTERICK ; NOTE THAT AN '*' WILL FILL THE REMAINING - JP NZ,CONVRT5 ; FIELD WITH '?'. - LD (HL),#QUESTION - JP CONVRT6 -CONVRT5:LD (HL),A - INC DE -CONVRT6:DEC B - JP NZ,CONVRT4 -CONVRT7:CALL CHECK ; GET NEXT DELIMITER. - JP Z,GETEXT - INC DE - JP CONVRT7 -CONVRT8:INC HL ; BLANK FILL THE FILE NAME. - LD (HL),#ASCSPACE - DEC B - JP NZ,CONVRT8 -; -; GET THE EXTENSION AND CONVERT IT. -; -GETEXT: LD B,#3 - CP #PERIOD - JP NZ,GETEXT5 - INC DE -GETEXT1:CALL CHECK - JP Z,GETEXT5 - INC HL - CP #ASTERICK - JP NZ,GETEXT2 - LD (HL),#QUESTION - JP GETEXT3 -GETEXT2:LD (HL),A - INC DE -GETEXT3:DEC B - JP NZ,GETEXT1 -GETEXT4:CALL CHECK - JP Z,GETEXT6 - INC DE - JP GETEXT4 -GETEXT5:INC HL - LD (HL),#ASCSPACE - DEC B - JP NZ,GETEXT5 -GETEXT6:LD B,#3 -GETEXT7:INC HL - LD (HL),#0 - DEC B - JP NZ,GETEXT7 - EX DE,HL - LD (INPOINT),HL ; SAVE INPUT LINE POINTER. - POP HL -; -; CHECK TO SEE IF THIS IS AN AMBIGEOUS FILE NAME SPECIFICATION. -; SET THE (A) REGISTER TO NON ZERO IF IT IS. -; - LD BC,#11 ; SET NAME LENGTH. -GETEXT8:INC HL - LD A,(HL) - CP #QUESTION ; ANY QUESTION MARKS? - JP NZ,GETEXT9 - INC B ; COUNT THEM. -GETEXT9:DEC C - JP NZ,GETEXT8 - LD A,B - OR A - RET -; -; CP/M COMMAND TABLE. NOTE COMMANDS CAN BE EITHER 3 OR 4 CHARACTERS LONG. -; - .if MON -NUMCMDS = 7 ; NUMBER OF COMMANDS - .else -NUMCMDS = 6 ; NUMBER OF COMMANDS - .endif - -CMDTBL: .ascii "DIR " - .ascii "ERA " - .ascii "TYPE" - .ascii "SAVE" - .ascii "REN " - .ascii "USER" - .if MON - .ascii "MON " - .ENDIF - -CMDADR: .DW DIRECT - .DW ERASE - .DW TYPE - .DW SAVE - .DW RENAME - .DW USER - .IF MON - .DW MONITOR - .ENDIF - .DW UNKNOWN -; -; SEARCH THE COMMAND TABLE FOR A MATCH WITH WHAT HAS JUST -; BEEN ENTERED. IF A MATCH IS FOUND, THEN WE JUMP TO THE -; PROPER SECTION. ELSE JUMP TO (UNKNOWN). -; ON RETURN, THE (C) REGISTER IS SET TO THE COMMAND NUMBER -; THAT MATCHED (OR NUMCMDS+1 IF NO MATCH). -; -SEARCH: LD HL,#CMDTBL - LD C,#0 -SEARCH1:LD A,C - CP #NUMCMDS ; THIS COMMANDS EXISTS. - RET NC - LD DE,#FCB+1 ; CHECK THIS ONE. - LD B,#4 ; MAX COMMAND LENGTH. -SEARCH2:LD A,(DE) - CP (HL) - JP NZ,SEARCH3 ; NOT A MATCH. - INC DE - INC HL - DEC B - JP NZ,SEARCH2 - LD A,(DE) ; ALLOW A 3 CHARACTER COMMAND TO MATCH. - CP #ASCSPACE - JP NZ,SEARCH4 - LD A,C ; SET RETURN REGISTER FOR THIS COMMAND. - RET -SEARCH3:INC HL - DEC B - JP NZ,SEARCH3 -SEARCH4:INC C - JP SEARCH1 -; -; SET THE INPUT BUFFER TO EMPTY AND THEN START THE COMMAND -; PROCESSOR (CCP). -; -CLEARBUF: - XOR A - LD (INBUFF+1),A ; SECOND BYTE IS ACTUAL LENGTH. -COMMAND:LD SP,#CCPSTACK ; SETUP STACK AREA. - PUSH BC ; NOTE THAT (C) SHOULD BE .EQUAL TO: - LD A,C ; (UUUUDDDD) WHERE 'UUUU' IS THE USER NUMBER - RRA ; AND 'DDDD' IS THE DRIVE NUMBER. - RRA - RRA - RRA - AND #0x0F ; ISOLATE THE USER NUMBER. - LD E,A - CALL GETSETUC ; AND SET IT. - CALL RESDSK ; RESET THE DISK SYSTEM. - LD (BATCH),A ; CLEAR BATCH MODE FLAG. - POP BC - LD A,C - AND #0x0F ; ISOLATE THE DRIVE NUMBER. - LD (CDRIVE),A ; AND SAVE. - CALL DSKSEL ; ...AND SELECT. - LD A,(INBUFF+1) - OR A ; ANYTHING IN INPUT BUFFER ALREADY? - JP NZ,CMMND2 ; YES, WE JUST PROCESS IT. -; -; ENTRY POINT TO GET A COMMAND LINE FROM THE CONSOLE. -; -CMMND1: LD SP,#CCPSTACK ; SET STACK STRAIGHT. - CALL CRLF ; START A NEW LINE ON THE SCREEN. - CALL GETDSK ; GET CURRENT DRIVE. - ADD A,#0x41 - CALL PRINT ; PRINT CURRENT DRIVE. - .IF USRDSP - CALL GETUSR ;GET CURRENT USER NUMBER - CP #10 ;TWO DIGITS? - JR C,CMMND3 ;NO - LD A,#0x31 ;PRINT LEADING '1' - CALL PRINT - CALL GETUSR ;GET CURRENT USER NUMBER - SUB #10 ;SUBTRACT 10 -CMMND3: ADD A,#0x30 - CALL PRINT - .ENDIF - LD A,#GREATERTHAN - CALL PRINT ; AND ADD PROMPT. - CALL GETINP ; GET LINE FROM USER. -; -; PROCESS COMMAND LINE HERE. -; -CMMND2: LD DE,#TBUFF - CALL DMASET ; SET STANDARD DMA ADDRESS. - CALL GETDSK - LD (CDRIVE),A ; SET CURRENT DRIVE. - CALL CONVFST ; CONVERT NAME TYPED IN. - CALL NZ,SYNERR ; WILD CARDS ARE NOT ALLOWED. - LD A,(CHGDRV) ; IF A CHANGE IN DRIVES WAS INDICATED, - OR A ; THEN TREAT THIS AS AN UNKNOWN COMMAND - JP NZ,UNKNOWN ; WHICH GETS EXECUTED. - CALL SEARCH ; ELSE SEARCH COMMAND TABLE FOR A MATCH. -; -; NOTE THAT AN UNKNOWN COMMAND RETURNS -; WITH (A) POINTING TO THE LAST ADDRESS -; IN OUR TABLE WHICH IS (UNKNOWN). -; - LD HL,#CMDADR ; NOW, LOOK THRU OUR ADDRESS TABLE FOR COMMAND (A). - LD E,A ; SET (DE) TO COMMAND NUMBER. - LD D,#0 - ADD HL,DE - ADD HL,DE ; (HL)=(CMDADR)+2*(COMMAND NUMBER). - LD A,(HL) ; NOW PICK OUT THIS ADDRESS. - INC HL - LD H,(HL) - LD L,A - JP (HL) ; NOW EXECUTE IT. -; -; READ ERROR WHILE TYPEING A FILE. -; -RDERROR:LD BC,#RDERR - JP PLINE -RDERR: .asciz "Read Error" - -; -; R.EQUIRED FILE WAS NOT LOCATED. -; -NONE: LD BC,#NOFILE - JP PLINE -NOFILE: .asciz "No File" -; -; DECODE A COMMAND OF THE FORM 'A>FILENAME NUMBER{ FILENAME}. -; NOTE THAT A DRIVE SPECIFIER IS NOT ALLOWED ON THE FIRST FILE -; NAME. ON RETURN, THE NUMBER IS IN REGISTER (A). ANY ERROR -; CAUSES 'FILENAME?' TO BE PRINTED AND THE COMMAND IS ABORTED. -; -DECODE: CALL CONVFST ; CONVERT FILENAME. - LD A,(CHGDRV) ; DO NOT ALLOW A DRIVE TO BE SPECIFIED. - OR A - JP NZ,SYNERR - LD HL,#FCB+1 ; CONVERT NUMBER NOW. - LD BC,#11 ; (B)=SUM REGISTER, (C)=MAX DIGIT COUNT. -DECODE1:LD A,(HL) - CP #ASCSPACE ; A SPACE TERMINATES THE NUMERAL. - JP Z,DECODE3 - INC HL - SUB #0x30 ; MAKE BINARY FROM ASCII. - CP #10 ; LEGAL DIGIT? - JP NC,SYNERR - LD D,A ; YES, SAVE IT IN (D). - LD A,B ; COMPUTE (B)=(B)*10 AND CHECK FOR OVERFLOW. - AND #0x0E0 - JP NZ,SYNERR - LD A,B - RLCA - RLCA - RLCA ; (A)=(B)*8 - ADD A,B ; .......*9 - JP C,SYNERR - ADD A,B ; .......*10 - JP C,SYNERR - ADD A,D ; ADD IN NEW DIGIT NOW. -DECODE2:JP C,SYNERR - LD B,A ; AND SAVE RESULT. - DEC C ; ONLY LOOK AT 11 DIGITS. - JP NZ,DECODE1 - RET -DECODE3:LD A,(HL) ; SPACES MUST FOLLOW (WHY?). - CP #ASCSPACE - JP NZ,SYNERR - INC HL -DECODE4:DEC C - JP NZ,DECODE3 - LD A,B ; SET (A)=THE NUMERIC VALUE ENTERED. - RET -; -; MOVE 3 BYTES FROM (HL) TO (DE). NOTE THAT THERE IS ONLY -; ONE REFERENCE TO THIS AT (A2D5H). -; -MOVE3: LD B,#3 -; -; MOVE (B) BYTES FROM (HL) TO (DE). -; -HL2DE: LD A,(HL) - LD (DE),A - INC HL - INC DE - DEC B - JP NZ,HL2DE - RET -; -; COMPUTE (HL)=(TBUFF)+(A)+(C) AND GET THE BYTE THAT'S HERE. -; -EXTRACT:LD HL,#TBUFF - ADD A,C - CALL ADDHL - LD A,(HL) - RET -; -; CHECK DRIVE SPECIFIED. IF IT MEANS A CHANGE, THEN THE NEW -; DRIVE WILL BE SELECTED. IN ANY CASE, THE DRIVE BYTE OF THE -; FCB WILL BE SET TO NULL (MEANS USE CURRENT DRIVE). -; -DSELECT:XOR A ; NULL OUT FIRST BYTE OF FCB. - LD (FCB),A - LD A,(CHGDRV) ; A DRIVE CHANGE INDICATED? - OR A - RET Z - DEC A ; YES, IS IT THE SAME AS THE CURRENT DRIVE? - LD HL,#CDRIVE - CP (HL) - RET Z - JP DSKSEL ; NO. SELECT IT THEN. -; -; CHECK THE DRIVE SELECTION AND RESET IT TO THE PREVIOUS -; DRIVE IF IT WAS CHANGED FOR THE PRECEEDING COMMAND. -; -RESETDR:LD A,(CHGDRV) ; DRIVE CHANGE INDICATED? - OR A - RET Z - DEC A ; YES, WAS IT A DIFFERENT DRIVE? - LD HL,#CDRIVE - CP (HL) - RET Z - LD A,(CDRIVE) ; YES, RE-SELECT OUR OLD DRIVE. - JP DSKSEL - - .IF MON -; -;************************************************************** -;* -;* M O N I T O R C O M M A N D -;* -;************************************************************** -; -MONITOR: JP MONADR - .ENDIF - -; -;************************************************************** -;* -;* D I R E C T O R Y C O M M A N D -;* -;************************************************************** -; -DIRECT: CALL CONVFST ; CONVERT FILE NAME. - CALL DSELECT ; SELECT INDICATED DRIVE. - LD HL,#FCB+1 ; WAS ANY FILE INDICATED? - LD A,(HL) - CP #ASCSPACE - JP NZ,DIRECT2 - LD B,#11 ; NO. FILL FIELD WITH '?' - SAME AS *.*. -DIRECT1:LD (HL),#QUESTION - INC HL - DEC B - JP NZ,DIRECT1 -DIRECT2:LD E,#0 ; SET INITIAL CURSOR POSITION. - PUSH DE - CALL SRCHFCB ; GET FIRST FILE NAME. - CALL Z,NONE ; NONE FOUND AT ALL? -DIRECT3:JP Z,DIRECT9 ; TERMINATE IF NO MORE NAMES. - LD A,(RTNCODE) ; GET FILE'S POSITION IN SEGMENT (0-3). - RRCA - RRCA - RRCA - AND #0x60 ; (A)=POSITION*32 - LD C,A - LD A,#10 - CALL EXTRACT ; EXTRACT THE TENTH ENTRY IN FCB. - RLA ; CHECK SYSTEM FILE STATUS BIT. - JP C,DIRECT8 ; WE DON'T LIST THEM. - POP DE - LD A,E ; BUMP NAME COUNT. - INC E - PUSH DE - AND #3 ; AT END OF LINE? - PUSH AF - JP NZ,DIRECT4 - CALL CRLF ; YES, END THIS LINE AND START ANOTHER. - PUSH BC - CALL GETDSK ; START LINE WITH ('A:'). - POP BC - ADD A,#0x41 - CALL PRINTB - LD A,#COLON - CALL PRINTB - JP DIRECT5 -DIRECT4:CALL SPACE ; ADD SEPERATOR BETWEEN FILE NAMES. - LD A,#COLON - CALL PRINTB -DIRECT5:CALL SPACE - LD B,#1 ; 'EXTRACT' EACH FILE NAME CHARACTER AT A TIME. -DIRECT6:LD A,B - CALL EXTRACT - AND #0x7F ; STRIP BIT 7 (STATUS BIT). - CP #ASCSPACE ; ARE WE AT THE END OF THE NAME? - JP NZ,DRECT65 - POP AF ; YES, DON'T PRINT SPACES AT THE END OF A LINE. - PUSH AF - CP #3 - JP NZ,DRECT63 - LD A,#9 ; FIRST CHECK FOR NO EXTENSION. - CALL EXTRACT - AND #0x7F - CP #ASCSPACE - JP Z,DIRECT7 ; DON'T PRINT SPACES. -DRECT63:LD A,#ASCSPACE ; ELSE PRINT THEM. -DRECT65:CALL PRINTB - INC B ; BUMP TO NEXT CHARACTER PSOITION. - LD A,B - CP #12 ; END OF THE NAME? - JP NC,DIRECT7 - CP #9 ; NOPE, STARTING EXTENSION? - JP NZ,DIRECT6 - CALL SPACE ; YES, ADD SEPERATING SPACE. - JP DIRECT6 -DIRECT7:POP AF ; GET THE NEXT FILE NAME. -DIRECT8:CALL CHKCON ; FIRST CHECK CONSOLE, QUIT ON ANYTHING. - JP NZ,DIRECT9 - CALL SRCHNXT ; GET NEXT NAME. - JP DIRECT3 ; AND CONTINUE WITH OUR LIST. -DIRECT9:POP DE ; RESTORE THE STACK AND RETURN TO COMMAND LEVEL. - JP GETBACK -; -;************************************************************** -;* -;* E R A S E C O M M A N D -;* -;************************************************************** -; -ERASE: CALL CONVFST ; CONVERT FILE NAME. - CP #11 ; WAS '*.*' ENTERED? - JP NZ,ERASE1 - LD BC,#YESNO ; YES, ASK FOR CONFIRMATION. - CALL PLINE - CALL GETINP - LD HL,#INBUFF+1 - DEC (HL) ; MUST BE EXACTLY 'Y'. - JP NZ,CMMND1 - INC HL - LD A,(HL) - CP #0x59 - JP NZ,CMMND1 - INC HL - LD (INPOINT),HL ; SAVE INPUT LINE POINTER. -ERASE1: CALL DSELECT ; SELECT DESIRED DISK. - LD DE,#FCB - CALL DELETE ; DELETE THE FILE. - INC A - CALL Z,NONE ; NOT THERE? - JP GETBACK ; RETURN TO COMMAND LEVEL NOW. -YESNO: .asciz "All (Y/N)?" -; -;************************************************************** -;* -;* T Y P E C O M M A N D -;* -;************************************************************** -; -TYPE: CALL CONVFST ; CONVERT FILE NAME. - JP NZ,SYNERR ; WILD CARDS NOT ALLOWED. - CALL DSELECT ; SELECT INDICATED DRIVE. - CALL OPENFCB ; OPEN THE FILE. - JP Z,TYPE5 ; NOT THERE? - CALL CRLF ; OK, START A NEW LINE ON THE SCREEN. - LD HL,#NBYTES ; INITIALIZE BYTE COUNTER. - LD (HL),#0x0FF ; SET TO READ FIRST SECTOR. -TYPE1: LD HL,#NBYTES -TYPE2: LD A,(HL) ; HAVE WE WRITTEN THE ENTIRE SECTOR? - CP #128 - JP C,TYPE3 - PUSH HL ; YES, READ IN THE NEXT ONE. - CALL READFCB - POP HL - JP NZ,TYPE4 ; END OR ERROR? - XOR A ; OK, CLEAR BYTE COUNTER. - LD (HL),A -TYPE3: INC (HL) ; COUNT THIS BYTE. - LD HL,#TBUFF ; AND GET THE (A)TH ONE FROM THE BUFFER (TBUFF). - CALL ADDHL - LD A,(HL) - CP #CNTRLZ ; END OF FILE MARK? - JP Z,GETBACK - CALL PRINT ; NO, PRINT IT. - CALL CHKCON ; CHECK CONSOLE, QUIT IF ANYTHING READY. - JP NZ,GETBACK - JP TYPE1 -; -; GET HERE ON AN END OF FILE OR READ ERROR. -; -TYPE4: DEC A ; READ ERROR? - JP Z,GETBACK - CALL RDERROR ; YES, PRINT MESSAGE. -TYPE5: CALL RESETDR ; AND RESET PROPER DRIVE - JP SYNERR ; NOW PRINT FILE NAME WITH PROBLEM. -; -;************************************************************** -;* -;* S A V E C O M M A N D -;* -;************************************************************** -; -SAVE: CALL DECODE ; GET NUMERIC NUMBER THAT FOLLOWS SAVE. - PUSH AF ; SAVE NUMBER OF PAGES TO WRITE. - CALL CONVFST ; CONVERT FILE NAME. - JP NZ,SYNERR ; WILD CARDS NOT ALLOWED. - CALL DSELECT ; SELECT SPECIFIED DRIVE. - LD DE,#FCB ; NOW DELETE THIS FILE. - PUSH DE - CALL DELETE - POP DE - CALL CREATE ; AND CREATE IT AGAIN. - JP Z,SAVE3 ; CAN'T CREATE? - XOR A ; CLEAR RECORD NUMBER BYTE. - LD (FCB+32),A - POP AF ; CONVERT PAGES TO SECTORS. - LD L,A - LD H,#0 - ADD HL,HL ; (HL)=NUMBER OF SECTORS TO WRITE. - LD DE,#TBASE ; AND WE START FROM HERE. -SAVE1: LD A,H ; DONE YET? - OR L - JP Z,SAVE2 - DEC HL ; NOPE, COUNT THIS AND COMPUTE THE START - PUSH HL ; OF THE NEXT 128 BYTE SECTOR. - LD HL,#128 - ADD HL,DE - PUSH HL ; SAVE IT AND SET THE TRANSFER ADDRESS. - CALL DMASET - LD DE,#FCB ; WRITE OUT THIS SECTOR NOW. - CALL WRTREC - POP DE ; RESET (DE) TO THE START OF THE LAST SECTOR. - POP HL ; RESTORE SECTOR COUNT. - JP NZ,SAVE3 ; WRITE ERROR? - JP SAVE1 -; -; GET HERE AFTER WRITING ALL OF THE FILE. -; -SAVE2: LD DE,#FCB ; NOW CLOSE THE FILE. - CALL CLOSE - INC A ; DID IT CLOSE OK? - JP NZ,SAVE4 -; -; PRINT OUT ERROR MESSAGE (NO SPACE). -; -SAVE3: LD BC,#NOSPACE - CALL PLINE -SAVE4: CALL STDDMA ; RESET THE STANDARD DMA ADDRESS. - JP GETBACK - -NOSPACE: .asciz "No Space" -; -;************************************************************** -;* -;* R E N A M E C O M M A N D -;* -;************************************************************** -; -RENAME: CALL CONVFST ; CONVERT FIRST FILE NAME. - JP NZ,SYNERR ; WILD CARDS NOT ALLOWED. - LD A,(CHGDRV) ; REMEMBER ANY CHANGE IN DRIVES SPECIFIED. - PUSH AF - CALL DSELECT ; AND SELECT THIS DRIVE. - CALL SRCHFCB ; IS THIS FILE PRESENT? - JP NZ,RENAME6 ; YES, PRINT ERROR MESSAGE. - LD HL,#FCB ; YES, MOVE THIS NAME INTO SECOND SLOT. - LD DE,#FCB+16 - LD B,#16 - CALL HL2DE - LD HL,(INPOINT) ; GET INPUT POINTER. - EX DE,HL - CALL NONBLANK ; GET NEXT NON BLANK CHARACTER. - CP #EQUAL ; ONLY ALLOW AN '=' OR '_' SEPERATOR. - JP Z,RENAME1 - CP #ASCSPACE - JP NZ,RENAME5 -RENAME1:EX DE,HL - INC HL ; OK, SKIP SEPERATOR. - LD (INPOINT),HL ; SAVE INPUT LINE POINTER. - CALL CONVFST ; CONVERT THIS SECOND FILE NAME NOW. - JP NZ,RENAME5 ; AGAIN, NO WILD CARDS. - POP AF ; IF A DRIVE WAS SPECIFIED, THEN IT - LD B,A ; MUST BE THE SAME AS BEFORE. - LD HL,#CHGDRV - LD A,(HL) - OR A - JP Z,RENAME2 - CP B - LD (HL),B - JP NZ,RENAME5 ; THEY WERE DIFFERENT, ERROR. -RENAME2:LD (HL),B ; RESET AS PER THE FIRST FILE SPECIFICATION. - XOR A - LD (FCB),A ; CLEAR THE DRIVE BYTE OF THE FCB. -RENAME3:CALL SRCHFCB ; AND GO LOOK FOR SECOND FILE. - JP Z,RENAME4 ; DOESN'T EXIST? - LD DE,#FCB - CALL RENAM ; OK, RENAME THE FILE. - JP GETBACK -; -; PROCESS RENAME ERRORS HERE. -; -RENAME4:CALL NONE ; FILE NOT THERE. - JP GETBACK -RENAME5:CALL RESETDR ; BAD COMMAND FORMAT. - JP SYNERR -RENAME6:LD BC,#EXISTS ; DESTINATION FILE ALREADY EXISTS. - CALL PLINE - JP GETBACK -EXISTS: .asciz "File Exists" -; -;************************************************************** -;* -;* U S E R C O M M A N D -;* -;************************************************************** -; -USER: CALL DECODE ; GET NUMERIC VALUE FOLLOWING COMMAND. - CP #16 ; LEGAL USER NUMBER? - JP NC,SYNERR - LD E,A ; YES BUT IS THERE ANYTHING ELSE? - LD A,(FCB+1) - CP #ASCSPACE - JP Z,SYNERR ; YES, THAT IS NOT ALLOWED. - CALL GETSETUC ; OK, SET USER CODE. - JP GETBACK1 -; -;************************************************************** -;* -;* T R A N S I A N T P R O G R A M C O M M A N D -;* -;************************************************************** -; -UNKNOWN:LD A,(FCB+1) ; ANYTHING TO EXECUTE? - CP #ASCSPACE - JP NZ,UNKWN1 - LD A,(CHGDRV) ; NOPE, ONLY A DRIVE CHANGE? - OR A - JP Z,GETBACK1 ; NEITHER??? - DEC A - LD (CDRIVE),A ; OK, STORE NEW DRIVE. - CALL MOVECD ; SET (TDRIVE) ALSO. - CALL DSKSEL ; AND SELECT THIS DRIVE. - JP GETBACK1 ; THEN RETURN. -; -; HERE A FILE NAME WAS TYPED. PREPARE TO EXECUTE IT. -; -UNKWN1: LD DE,#FCB+9 ; AN EXTENSION SPECIFIED? - LD A,(DE) - CP #ASCSPACE - JP NZ,SYNERR ; YES, NOT ALLOWED. -UNKWN2: PUSH DE - CALL DSELECT ; SELECT SPECIFIED DRIVE. - POP DE - LD HL,#COMFILE ; SET THE EXTENSION TO 'COM'. LD HL,COMFILE - CALL MOVE3 ; move 3 bytes from (HL) to (DE) to add .COM - CALL OPENFCB ; AND OPEN THIS FILE. - JP NZ,UNKWNA ;GOT IT - .IF CHKU0B - LD E,#0 ;TRY USER 0, THIS DRIVE - CALL GETSETUC ; OK, SET USER CODE. - CALL OPENFCB - JP NZ,UNKWNA ;GOT IT - LD HL,#FCB ;SEE IF ON DRIVE B, USER 0 - LD (HL),#2 - CALL OPENFCB - JP Z,UNKWN9 ;NOPE - .ENDIF -; -; LOAD IN THE PROGRAM. -; -UNKWNA: LD HL,#TBASE ; STORE THE PROGRAM STARTING HERE. -UNKWN3: PUSH HL - EX DE,HL - CALL DMASET ; SET TRANSFER ADDRESS. - LD DE,#FCB ; AND READ THE NEXT RECORD. - CALL RDREC - JP NZ,UNKWN4 ; END OF FILE OR READ ERROR? - POP HL ; NOPE, BUMP POINTER FOR NEXT SECTOR. - LD DE,#128 - ADD HL,DE - LD DE,#CBASE ; ENOUGH ROOM FOR THE WHOLE FILE? - LD A,L - SUB E - LD A,H - SBC A,D - JP NC,UNKWN0 ; NO, IT CAN'T FIT. - JP UNKWN3 -; -; GET HERE AFTER FINISHED READING. -; -UNKWN4: POP HL - DEC A ; NORMAL END OF FILE? - JP NZ,UNKWN0 - CALL RESETDR ; YES, RESET PREVIOUS DRIVE. - CALL CONVFST ; CONVERT THE FIRST FILE NAME THAT FOLLOWS - LD HL,#CHGDRV ; COMMAND NAME. - PUSH HL - LD A,(HL) ; SET DRIVE CODE IN DEFAULT FCB. - LD (FCB),A - LD A,#16 ; PUT SECOND NAME 16 BYTES LATER. - CALL CONVERT ; CONVERT SECOND FILE NAME. - POP HL - LD A,(HL) ; AND SET THE DRIVE FOR THIS SECOND FILE. - LD (FCB+16),A - XOR A ; CLEAR RECORD BYTE IN FCB. - LD (FCB+32),A - LD DE,#TFCB ; MOVE IT INTO PLACE AT(005CH). - LD HL,#FCB - LD B,#33 - CALL HL2DE - LD HL,#INBUFF+2 ; NOW MOVE THE REMAINDER OF THE INPUT -UNKWN5: LD A,(HL) ; LINE DOWN TO (0080H). LOOK FOR A NON BLANK. - OR A ; OR A NULL. - JP Z,UNKWN6 - CP #ASCSPACE - JP Z,UNKWN6 - INC HL - JP UNKWN5 -; -; DO THE LINE MOVE NOW. IT ENDS IN A NULL BYTE. -; -UNKWN6: LD B,#0 ; KEEP A CHARACTER COUNT. - LD DE,#TBUFF+1 ; DATA GETS PUT HERE. -UNKWN7: LD A,(HL) ; MOVE IT NOW. - LD (DE),A - OR A - JP Z,UNKWN8 - INC B - INC HL - INC DE - JP UNKWN7 -UNKWN8: LD A,B ; NOW STORE THE CHARACTER COUNT. - LD (TBUFF),A - CALL CRLF ; CLEAN UP THE SCREEN. - CALL STDDMA ; SET STANDARD TRANSFER ADDRESS. - CALL SETCDRV ; RESET CURRENT DRIVE. - CALL TBASE ; AND EXECUTE THE PROGRAM. -; -; TRANSIANT PROGRAMS RETURN HERE (OR REBOOT). -; - LD SP,#BATCH ; SET STACK FIRST OFF. - CALL MOVECD ; MOVE CURRENT DRIVE INTO PLACE (TDRIVE). - CALL DSKSEL ; AND RESELECT IT. - JP CMMND1 ; BACK TO COMAND MODE. -; -; GET HERE IF SOME ERROR OCCURED. -; -UNKWN9: CALL RESETDR ; INPROPER FORMAT. - JP SYNERR -UNKWN0: LD BC,#BADLOAD ; READ ERROR OR WON'T FIT. - CALL PLINE - JP GETBACK -BADLOAD:.asciz "Bad Load" -COMFILE:.ascii "COM" ; COMMAND FILE EXTENSION. -; -; GET HERE TO RETURN TO COMMAND LEVEL. WE WILL RESET THE -; PREVIOUS ACTIVE DRIVE AND THEN EITHER RETURN TO COMMAND -; LEVEL DIRECTLY OR PRINT ERROR MESSAGE AND THEN RETURN. -; -GETBACK:CALL RESETDR ; RESET PREVIOUS DRIVE. -GETBACK1: - CALL CONVFST ; CONVERT FIRST NAME IN (FCB). - LD A,(FCB+1) ; IF THIS WAS JUST A DRIVE CHANGE R.EQUEST, - SUB #ASCSPACE ; MAKE SURE IT WAS VALID. - LD HL,#CHGDRV - OR (HL) - JP NZ,SYNERR - JP CMMND1 ; OK, RETURN TO COMMAND LEVEL. -; -; CCP STACK AREA. -; - .DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -CCPSTACK: -;dwg; .EQU $ ;END OF CCP STACK AREA. - -; -; BATCH (OR SUBMIT) PROCESSING INFORMATION STORAGE. -; -BATCH: .DB 0 ; BATCH MODE FLAG (0=NOT ACTIVE). -BATCHFCB:.DB 0 - .ascii "$$$ SUB" - .DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -; -; FILE CONTROL BLOCK SETUP BY THE CCP. -; -FCB: .DB 0 - .asciz " " - .DB 0,0,0,0 - - .asciz " " - .DB 0,0,0,0 - -RTNCODE:.DB 0 ; STATUS RETURNED FROM BDOS CALL. -CDRIVE: .DB 0 ; CURRENTLY ACTIVE DRIVE. -CHGDRV: .DB 0 ; CHANGE IN DRIVES FLAG (0=NO CHANGE). -NBYTES: .DW 0 ; BYTE COUNTER USED BY TYPE. - -;dwg; .IF ENDFIL -;dwg; .ORG CCPO+07FFH -;dwg; .DB 055H -;dwg; .ENDIF -;dwg; .END - - -_ccp_end:: - .area _CODE - .area _CABS diff --git a/doug/src/ccpb03.sym b/doug/src/ccpb03.sym deleted file mode 100755 index 3c421d12..00000000 --- a/doug/src/ccpb03.sym +++ /dev/null @@ -1,83 +0,0 @@ - ASxxxx Assembler V02.00 + NoICE + SDCC mods + Flat24 (Zilog Z80 / Hitachi HD64180), page 1. -ccpb03.s derived from ccpb03.asm -Symbol Table - - .__.ABS.= 0000 G | 6 ADDHL 0243 R | ASCSPACE= 0020 - ASTERICK= 002A | 6 BADLOAD 0786 R | BASE = 9C00 - 6 BATCH 07B7 R | 6 BATCHFCB 07B8 R | BDOSO = D800 - BIOSO = E600 | BS = 0008 | 6 CBASE 0000 R - CCPO = D000 | 6 CCPSTACK 07B7 R | 6 CDRIVE 07FB R - 6 CHECK 021A R | 6 CHGDRV 07FC R | 6 CHKCON 01C0 R - CHKU0B = 0001 | 6 CLEARBUF 0350 R | 6 CLOSE 00D8 R - 6 CMDADR 0316 R | 6 CMDTBL 02FA R | 6 CMMND1 037A R - 6 CMMND2 03A6 R | 6 CMMND3 0399 R | CNTRLC = 0003 - CNTRLE = 0005 | CNTRLP = 0010 | CNTRLR = 0012 - CNTRLS = 0013 | CNTRLU = 0015 | CNTRLX = 0018 - CNTRLZ = 001A | COLON = 003A | 6 COMFILE 078F R - 6 COMMAND 0354 R | 6 CONVERT 024A R | 6 CONVFST 0248 R - 6 CONVRT1 0273 R | 6 CONVRT2 027A R | 6 CONVRT3 0280 R - 6 CONVRT4 0282 R | 6 CONVRT5 0293 R | 6 CONVRT6 0295 R - 6 CONVRT7 0299 R | 6 CONVRT8 02A3 R | CR = 000D - 6 CREATE 0107 R | 6 CRLF 0096 R | 6 DECODE 03EE R - 6 DECODE1 03FE R | 6 DECODE2 0420 R | 6 DECODE3 0429 R - 6 DECODE4 0430 R | DEL = 007F | 6 DELBATCH 01DB R - 6 DELETE 00ED R | 6 DIRECT 0470 R | 6 DIRECT1 0481 R - 6 DIRECT2 0488 R | 6 DIRECT3 0491 R | 6 DIRECT4 04C5 R - 6 DIRECT5 04CD R | 6 DIRECT6 04D2 R | 6 DIRECT7 0507 R - 6 DIRECT8 0508 R | 6 DIRECT9 0514 R | 6 DMASET 01D6 R - 6 DRECT63 04F0 R | 6 DRECT65 04F2 R | 6 DSELECT 044A R - 6 DSKSEL 00BB R | ENDFIL = 0001 | ENTRY = 0005 - 6 ENTRY1 00C1 R | 6 ENTRY2 00F2 R | EQUAL = 003D - 6 ERASE 0518 R | 6 ERASE1 053B R | 6 EXISTS 067B R - 6 EXTRACT 0441 R | 6 FCB 07D9 R | FF = 000C - 6 GETBACK 0792 R | 6 GETBACK1 0795 R | 6 GETDSK 01CE R - 6 GETEXT 02AA R | 6 GETEXT1 02B2 R | 6 GETEXT2 02C3 R - 6 GETEXT3 02C5 R | 6 GETEXT4 02C9 R | 6 GETEXT5 02D3 R - 6 GETEXT6 02DA R | 6 GETEXT7 02DC R | 6 GETEXT8 02EB R - 6 GETEXT9 02F3 R | 6 GETINP 0137 R | 6 GETINP1 0194 R - 6 GETINP2 01A5 R | 6 GETINP3 01A9 R | 6 GETINP4 01B8 R - 6 GETSETUC 0113 R | 6 GETUSR 0111 R | GREATERT= 003E - 6 HL2DE 0438 R | 6 INBUFF 0006 R | 6 INPOINT 0086 R - IOBYTE = 0003 | LCURLY = 007B | LESSTHAN= 003C - LF = 000A | MON = 0001 | MONADR = FC00 - 6 MONITOR 046D R | 6 MOVE3 0436 R | 6 MOVECD 0127 R - 6 NAMEPNT 0088 R | 6 NBYTES 07FD R | NK = 003B - 6 NOFILE 03E6 R | 6 NONBLANK 0239 R | 6 NONE 03E0 R - 6 NOSPACE 0600 R | NUMCMDS = 0007 | 6 OPEN 00C9 R - 6 OPENFCB 00CE R | PERIOD = 002E | 6 PLINE 00A5 R - 6 PLINE2 00AA R | 6 PRINT 008A R | 6 PRINTB 0090 R - QUESTION= 003F | 6 RDERR 03D5 R | 6 RDERROR 03CF R - 6 RDREC 00F7 R | 6 READFCB 00FC R | 6 RENAM 010C R - 6 RENAME 0609 R | 6 RENAME1 0638 R | 6 RENAME2 0652 R - 6 RENAME3 0657 R | 6 RENAME4 0666 R | 6 RENAME5 066C R - 6 RENAME6 0672 R | 6 RESDSK 00B6 R | 6 RESETDR 045C R - 6 RTNCODE 07FA R | 6 SAVE 05A6 R | 6 SAVE1 05CD R - 6 SAVE2 05EA R | 6 SAVE3 05F4 R | 6 SAVE4 05FA R - 6 SEARCH 0326 R | 6 SEARCH1 032B R | 6 SEARCH2 0334 R - 6 SEARCH3 0347 R | 6 SEARCH4 034C R | 6 SETCDRV 0118 R - 6 SPACE 00A0 R | 6 SRCHFCB 00E7 R | 6 SRCHFST 00DD R - 6 SRCHNXT 00E2 R | 6 STDDMA 01D3 R | 6 SYNERR 01F3 R - 6 SYNERR1 01F9 R | 6 SYNERR2 020C R | TAB = 0009 - TBASE = 0100 | TBUFF = 0080 | TDRIVE = 0004 - TFCB = 005C | 6 TYPE 0556 R | 6 TYPE1 056D R - 6 TYPE2 0570 R | 6 TYPE3 0580 R | 6 TYPE4 0599 R - 6 TYPE5 05A0 R | UNDERSCO= 005F | 6 UNKNOWN 069E R - 6 UNKWN0 077D R | 6 UNKWN1 06BA R | 6 UNKWN2 06C3 R - 6 UNKWN3 06ED R | 6 UNKWN4 070D R | 6 UNKWN5 073C R - 6 UNKWN6 074A R | 6 UNKWN7 074F R | 6 UNKWN8 075B R - 6 UNKWN9 0777 R | 6 UNKWNA 06EA R | 6 UPPER 012E R - 6 USER 0687 R | USRDSP = 0001 | 6 WRTREC 0102 R - 6 YESNO 054B R | 6 _ccp 0000 GR | 6 _ccp_end 07FF GR - 6 _ccp_sta 0000 GR - ASxxxx Assembler V02.00 + NoICE + SDCC mods + Flat24 (Zilog Z80 / Hitachi HD64180), page 2. -ccpb03.s derived from ccpb03.asm -Area Table - - 0 _CODE size 0 flags 0 - 1 _DATA size 0 flags 0 - 2 _OVERLAY size 0 flags 0 - 3 _HOME size 0 flags 0 - 4 _GSINIT size 0 flags 0 - 5 _GSFINAL size 0 flags 0 - 6 _CCPB03 size 7FF flags 0 - 7 _CABS size 0 flags 0 diff --git a/doug/src/copyfile.arf b/doug/src/copyfile.arf deleted file mode 100755 index 1d3cdcc2..00000000 --- a/doug/src/copyfile.arf +++ /dev/null @@ -1,9 +0,0 @@ --mjx --i copyfile.ihx --k /usr/local/share/sdcc/lib/z80 --l z80 -cpm0.rel -copyfile.rel -cpmbdos.rel -cprintf.rel --e diff --git a/doug/src/copyfile.c b/doug/src/copyfile.c deleted file mode 100755 index c2ef45c4..00000000 --- a/doug/src/copyfile.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * copyfile.c 5/11/2011 dwg - - * Main C module uses cpmbdos.h bindings to access system services - * Copyright (C) Douglas Goodall All Rights Reserved - * For non-commercial use by N8VEM Community -*/ - -#include -#include -#include -#include "stdlib.h" -#include "cpmbdos.h" -#include "cprintf.h" - -char sine[] = "copyfile.c(com) 5/11/2011 dwg - $"; - -struct FCB * prifcb = (struct FCB *)0x5c; -struct FCB * secfcb = (struct FCB *)0x6c; - -struct FCB srcfcb; -struct FCB dstfcb; - -struct BDOSCALL writestr = { C_WRITESTR, { (unsigned int)&sine } }; -struct BDOSCALL makedst = { F_MAKE, { (unsigned int)&dstfcb } }; -struct BDOSCALL opensrc = { F_OPEN, { (unsigned int)&srcfcb } }; -struct BDOSCALL readsrc = { F_READ, { (unsigned int)&srcfcb } }; -struct BDOSCALL writedst = { F_WRITE, { (unsigned int)&dstfcb } }; -struct BDOSCALL closesrc = { F_CLOSE, { (unsigned int)&srcfcb } }; -struct BDOSCALL closedst = { F_CLOSE, { (unsigned int)&dstfcb } }; - -struct BDOSCALL cwrite = { C_WRITE, { (unsigned int)'?' } }; -struct BDOSCALL cread = { C_READ, { (unsigned int)0 } }; - -/* THESE ARE USED BY THE LIBRARY ROUTINES */ -char getchar(void) -{ - struct BDOSCALL cread = { C_READ, { (unsigned int)0 } }; - return cpmbdos(&cread); -} -void outchar(char c) -{ - struct BDOSCALL cwrite = { C_WRITE, { (unsigned int)c } }; - cpmbdos(&cwrite); -} - -int main(void) -{ - int rc; - - cpmbdos(&writestr); - - strncpy(srcfcb.filename,prifcb->filename,8+3); - srcfcb.ex = srcfcb.rc = srcfcb.cr = 0; - rc = cpmbdos(&opensrc); printf("\nrc from opensrc was %2d, ",rc); - if(rc != 0) { - printf("\nSorry, cannot open source file\n"); - return(EXIT_FAILURE); - } - - strncpy(dstfcb.filename,secfcb->filename,8+3); - dstfcb.ex = dstfcb.rc = dstfcb.cr = 0; - rc = cpmbdos(&makedst); printf("rc from makedst was %2d",rc); - if(rc != 0) { - printf("\nSorry, cannot open destination file\n"); - cpmbdos(&closesrc); - return(EXIT_FAILURE); - } - - rc = cpmbdos(&readsrc); printf("\nrc from read was %2d, ",rc); - while(0 == rc) { - rc = cpmbdos(&writedst); printf( "rc from write was %2d", rc); - rc = cpmbdos(&readsrc); printf("\nrc from read was %2d, ",rc); - } - rc = cpmbdos(&closesrc); printf("\nrc from closesrc was %2d, ",rc); - rc = cpmbdos(&closedst); printf( "rc from closedst was %2d", rc); - - return EXIT_SUCCESS; -} - diff --git a/doug/src/copyfile.lk b/doug/src/copyfile.lk deleted file mode 100755 index 1d3cdcc2..00000000 --- a/doug/src/copyfile.lk +++ /dev/null @@ -1,9 +0,0 @@ --mjx --i copyfile.ihx --k /usr/local/share/sdcc/lib/z80 --l z80 -cpm0.rel -copyfile.rel -cpmbdos.rel -cprintf.rel --e diff --git a/doug/src/copyfile.lnk b/doug/src/copyfile.lnk deleted file mode 100755 index 1d3cdcc2..00000000 --- a/doug/src/copyfile.lnk +++ /dev/null @@ -1,9 +0,0 @@ --mjx --i copyfile.ihx --k /usr/local/share/sdcc/lib/z80 --l z80 -cpm0.rel -copyfile.rel -cpmbdos.rel -cprintf.rel --e diff --git a/doug/src/cpm0.lst b/doug/src/cpm0.lst deleted file mode 100755 index ae386b18..00000000 --- a/doug/src/cpm0.lst +++ /dev/null @@ -1,46 +0,0 @@ - 1 ;-------------------------------------------------------------------------- - 2 ; cpm0.s - Generic cpm0.s for a Z80 CP/M-80 v2.2 Application - 3 ; Copyright (C) 2011, Douglas Goodall All Rights Reserved. - 4 ;-------------------------------------------------------------------------- - 5 - 6 .globl _main - 7 .area _CODE - 8 - 0000 9 .ds 0x0100 - 0100 10 init: - 11 ;; Define an adequate stack - 0100 31r00s01 12 ld sp,#stktop - 13 - 14 ;; Initialise global variables - 0103 CDr00s00 15 call gsinit - 16 - 17 ;; Call the C main routine - 0106 CDr00s00 18 call _main - 19 - 0109 0E 00 20 ld c,#0 - 010B CD 05 00 21 call 5 - 22 - 23 ;; Ordering of segments for the linker. - 24 .area _TPA - 25 - 26 .area _HOME - 27 .area _CODE - 28 .area _GSINIT - 29 .area _GSFINAL - 30 .area _DATA - 31 - 32 .area _STACK - 0000 33 .ds 256 - 0100 34 stktop: - 35 - 36 .area _GSINIT - 0000 37 gsinit:: - 38 - 39 .area _GSFINAL - 0000 C9 40 ret - 0001 E5 41 .db 0xe5 - 42 - 43 ;;;;;;;;;;;;;;;; - 44 ; eof - cpm0.s ; - 45 ;;;;;;;;;;;;;;;; - 46 diff --git a/doug/src/cpm0.rel b/doug/src/cpm0.rel deleted file mode 100755 index a44191b5..00000000 --- a/doug/src/cpm0.rel +++ /dev/null @@ -1,26 +0,0 @@ -XL -H 7 areas 3 global symbols -S _main Ref0000 -S .__.ABS. Def0000 -A _CODE size 10E flags 0 addr 0 -A _TPA size 0 flags 0 addr 0 -A _HOME size 0 flags 0 addr 0 -A _GSINIT size 0 flags 0 addr 0 -S gsinit Def0000 -A _GSFINAL size 2 flags 0 addr 0 -A _DATA size 0 flags 0 addr 0 -A _STACK size 100 flags 0 addr 0 -T 00 00 -R 00 00 00 00 -T 00 01 -R 00 00 00 00 -T 00 01 31 00 01 CD 00 00 CD 00 00 0E 00 CD 05 00 -R 00 00 00 00 00 03 06 00 00 06 03 00 02 09 00 00 -T 00 00 -R 00 00 06 00 -T 00 01 -R 00 00 06 00 -T 00 00 -R 00 00 03 00 -T 00 00 C9 E5 -R 00 00 04 00 diff --git a/doug/src/cpm0.s b/doug/src/cpm0.s deleted file mode 100755 index 6e9191ea..00000000 --- a/doug/src/cpm0.s +++ /dev/null @@ -1,46 +0,0 @@ -;-------------------------------------------------------------------------- -; cpm0.s - Generic cpm0.s for a Z80 CP/M-80 v2.2 Application -; Copyright (C) 2011, Douglas Goodall All Rights Reserved. -;-------------------------------------------------------------------------- - - .globl _main - .area _CODE - - .ds 0x0100 -init: - ;; Define an adequate stack - ld sp,#stktop - - ;; Initialise global variables - call gsinit - - ;; Call the C main routine - call _main - - ld c,#0 - call 5 - - ;; Ordering of segments for the linker. - .area _TPA - - .area _HOME - .area _CODE - .area _GSINIT - .area _GSFINAL - .area _DATA - - .area _STACK - .ds 256 -stktop: - - .area _GSINIT -gsinit:: - - .area _GSFINAL - ret - .db 0xe5 - -;;;;;;;;;;;;;;;; -; eof - cpm0.s ; -;;;;;;;;;;;;;;;; - diff --git a/doug/src/cpm0.sym b/doug/src/cpm0.sym deleted file mode 100755 index 706615a9..00000000 --- a/doug/src/cpm0.sym +++ /dev/null @@ -1,17 +0,0 @@ - ASxxxx Assembler V02.00 + NoICE + SDCC mods + Flat24 (Zilog Z80 / Hitachi HD64180), page 1. - -Symbol Table - - .__.ABS.= 0000 G | _main **** GX | 3 gsinit 0000 GR - 0 init 0100 R | 6 stktop 0100 R - ASxxxx Assembler V02.00 + NoICE + SDCC mods + Flat24 (Zilog Z80 / Hitachi HD64180), page 2. - -Area Table - - 0 _CODE size 10E flags 0 - 1 _TPA size 0 flags 0 - 2 _HOME size 0 flags 0 - 3 _GSINIT size 0 flags 0 - 4 _GSFINAL size 2 flags 0 - 5 _DATA size 0 flags 0 - 6 _STACK size 100 flags 0 diff --git a/doug/src/cpm22.s b/doug/src/cpm22.s deleted file mode 100755 index 512e7228..00000000 --- a/doug/src/cpm22.s +++ /dev/null @@ -1,2989 +0,0 @@ -; modified 4/22/2011 for the N8VEM Home Computer Z180 -- John Coffman -; -;-------------------------------------------------------------------------- -; cpm22.s - CP/M-80 v2.2 for a Z80 -; -; Copyright (C) 2000, Michael Hope -; -; This library is free software; you can redistribute it and/or modify it -; under the terms of the GNU General Public License as published by the -; Free Software Foundation; either version 2.1, or (at your option) any -; later version. -; -; This library is distributed in the hope that it will be useful, -; but WITHOUT ANY WARRANTY; without even the implied warranty of -; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -; GNU General Public License for more details. -; -; You should have received a copy of the GNU General Public License -; along with this library; see the file COPYING. If not, write to the -; Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, -; MA 02110-1301, USA. -; -; As a special exception, if you link this library with other files, -; some of which are compiled with SDCC, to produce an executable, -; this library does not by itself cause the resulting executable to -; be covered by the GNU General Public License. This exception does -; not however invalidate any other reasons why the executable file -; might be covered by the GNU General Public License. -;-------------------------------------------------------------------------- - -;;; .module crt0 - .globl _main - - .area _HEADER (ABS) - ;; Reset vector - .org 0 - jp init - - .org 0x08 - ret - .org 0x10 - ret - .org 0x18 - ret - .org 0x20 - ret - .org 0x28 - ret - .org 0x30 - ret - .org 0x38 - ret - .org 0x66 ; NMI interrupt - retn - -;; .org 0x100 -;;init: -;; ;; Stack at the top of memory. -;; ld sp,#0xffff -;; -;; ;; Initialise global variables -;; call gsinit -;; call _main -;; jp _exit - - - -;; title 'Bdos Interface, Bdos, Version 2.2 Feb, 1980' -;; -;; .Z80 -;; aseg - - org 100h - - maclib MEMCFG.LIB ; define configuration parameters - -;; .phase bdosph -;;bios equ biosph - -;***************************************************************** -;***************************************************************** -;** ** -;** B a s i c D i s k O p e r a t i n g S y s t e m ** -;** I n t e r f a c e M o d u l e ** -;** ** -;***************************************************************** -;***************************************************************** - -; Copyright (c) 1978, 1979, 1980 -; Digital Research -; Box 579, Pacific Grove -; California - - -; 20 january 1980 - -ssize equ 24 ;24 level stack - -; low memory locations - -;;reboot equ 0000h ;reboot system -reboot = 0x0000 - -;;ioloc equ 0003h ;i/o byte location -ioloc = 0x0003 - -;;bdosa equ 0006h ;address field of jp BDOS -bdosa = 0x0006 - -; bios access constants - -bootf defl bios+3*0 ;cold boot function - -wbootf defl bios+3*1 ;warm boot function - -constf defl bios+3*2 ;console status function - -coninf defl bios+3*3 ;console input function - -conoutf defl bios+3*4 ;console output function - -listf defl bios+3*5 ;list output function - -punchf defl bios+3*6 ;punch output function - -readerf defl bios+3*7 ;reader input function - -homef defl bios+3*8 ;disk home function - -seldskf defl bios+3*9 ;select disk function - -settrkf defl bios+3*10 ;set track function - -setsecf defl bios+3*11 ;set sector function - -setdmaf defl bios+3*12 ;set dma function - -readf defl bios+3*13 ;read disk function - -writef defl bios+3*14 ;write disk function - -liststf defl bios+3*15 ;list status function - -sectran defl bios+3*16 ;sector translate - - -; equates for non graphic characters - -;;ctlc .equ 03h ;control c -ctlc = 0x03 - -;;ctle equ 05h ;physical eol -ctle = 0x05 - -;;ctlh equ 08h ;backspace -ctlh = 0x08 - -;;ctlp equ 10h ;prnt toggle -ctlp = 0x10 - -;;ctlr equ 12h ;repeat line -ctlr = 0x12 - -;;ctls equ 13h ;stop/start screen -ctls = 0x13 - -;;ctlu equ 15h ;line delete -ctlu = 0x15 - -;;ctlx equ 18h ;=ctl-u -ctlx = 0x18 - -;;ctlz equ 1ah ;end of file -ctlz = 0x1a - -;;rubout equ 7fh ;char delete -rubout = 0x7f - -;;tab equ 09h ;tab char -tab = 0x09 - -;;cr equ 0dh ;carriage return -cr = 0x0d - -;;lf equ 0ah ;line feed -lf = 0x0a - -;;ctl equ 5eh ;up arrow -ctl equ 0x5e - - .db 0,0,0,0,0,0 - -; enter here from the user's program with function number in c, -; and information address in d,e - jp bdose ;past parameter block - -; ************************************************ -; *** relative locations 0009 - 000e *** -; ************************************************ -pererr: .dw persub ;permanent error subroutine -selerr: .dw selsub ;select error subroutine -roderr: .dw rodsub ;ro disk error subroutine -roferr: .dw rofsub ;ro file error subroutine - - -bdose: ex de,hl ;arrive here from user programs - ld (info),hl - ex de,hl ;info=DE, DE=info - ld a,e - ld (linfo),a ;linfo = low(info) - don't equ - ld hl,0 - ld (aret),hl ;return value defaults to 0000 - ;save user's stack pointer, set to local stack - add hl,sp - ld (entsp),hl ;entsp = stackptr - ld sp,lstack ;local stack setup - xor a - ld (fcbdsk),a - ld (resel),a ;fcbdsk,resel=false - ld hl,goback ;return here after all functions - push hl ;jmp goback equivalent to ret - ld a,c - cp nfuncs - ret nc ;skip if invalid # - ld c,e ;possible output character to C - ld hl,functab - ld e,a - ld d,0 ;DE=func, HL=.ciotab - add hl,de - add hl,de - ld e,(hl) - inc hl - ld d,(hl) ;DE=functab(func) - ld hl,(info) ;info in DE for later xchg - ex de,hl - jp (hl) ;dispatched - -; dispatch table for functions -functab: - .dw wbootf, func1, func2, func3 - .dw punchf, listf, func6, func7 - .dw func8, func9, func10,func11 - -;;diskf equ ($-functab)/2 ;disk funcs -diskf = ($-functab)/2 ;disk funcs - - .dw func12,func13,func14,func15 - .dw func16,func17,func18,func19 - .dw func20,func21,func22,func23 - .dw func24,func25,func26,func27 - .dw func28,func29,func30,func31 - .dw func32,func33,func34,func35 - .dw func36,func37,func38,func39 - .dw func40 - -;;nfuncs equ ($-functab)/2 -nfuncs = ($-functab)/2 - -; error subroutines -persub: ld hl,permsg ;report permanent error - call errflg ;to report the error - cp ctlc - jp z,reboot ;reboot if response is ctlc - ret ;and ignore the error - -selsub: ld hl,selmsg ;report select error - jp wait$err ;wait console before boot - -rodsub: ld hl,rodmsg ;report write to read/only disk - jp wait$err ;wait console - -rofsub: ;report read/only file - ld hl,rofmsg ;drop through to wait for console - -wait$err: ;wait for response before boot - call errflg - jp reboot - -; error messages - -;;dskmsg: db 'Bdos Err On ' -dskmsg .ascii ' : $' - -;;dskerr: db ' : $' ;filled in by errflg -dskerr .ascii ' : $' - -;;permsg: db 'Bad Sector$' -permsg: .ascii 'Bad Sector$' - -;;selmsg: db 'Select$' -selmsg: .ascii 'Select$' - -;;rofmsg: db 'File ' -rofmsg: .asccii 'File ' - -;;rodmsg: db 'R/O$' -rodmsg: .ascii 'R/O$' - - -errflg: push hl ;report error to console, message address in HL - call crlf ;stack mssg address, new line - ld a,(curdsk) - add a,'A' - ld (dskerr),a ;current disk name - ld bc,dskmsg - call print ;the error message - pop bc - call print ;error mssage tail -; jp conin ;to get the input character - ;(drop through to conin) -; ret - - -; console handlers -conin: ld hl,kbchar ;read console character to A - ld a,(hl) - ld (hl),0 - or a - ret nz - ;no previous keyboard character ready - jp coninf ;get character externally -; ret -conech: call conin ;read character with echo - call echoc - ret c ;echo character? - ;character must be echoed before return - push af - ld c,a - call tabout - pop af - ret ;with character in A - -echoc: ;echo character if graphic - cp cr ;cr, lf, tab, or backspace - ret z ;carriage return? - cp lf - ret z ;line feed? - cp tab - ret z ;tab? - cp ctlh - ret z ;backspace? - cp ' ' - ret ;carry set if not graphic - -conbrk: ;check for character ready - ld a,(kbchar) - or a - jp nz,conb1 ;skip if active kbchar - ;no active kbchar, check external break - call constf - and 1 - ret z ;return if no char ready - ;character ready, read it - call coninf ;to A - cp ctls - jp nz,conb0 ;check stop screen function - ;found ctls, read next character - call coninf ;to A - cp ctlc - jp z,reboot ;ctlc implies re-boot - ;not a reboot, act as if nothing has happened - xor a - ret ;with zero in accumulator -conb0: - ;character in accum, save it - ld (kbchar),a -conb1: - ;return with true set in accumulator - ld a,1 - ret - -conout: ;compute character position/write console char from C - ;compcol = true if computing column position - ld a,(compcol) - or a - jp nz,compout - ;write the character, then compute the column - ;write console character from C - push bc - call conbrk ;check for screen stop function - pop bc - push bc ;recall/save character - call conoutf ;externally, to console - pop bc - push bc ;recall/save character - ;may be copying to the list device - ld a,(listcp) - or a - call nz,listf ;to printer, if so - pop bc ;recall the character -compout: - ld a,c ;recall the character - ;and compute column position - ld hl,column ;A = char, HL = .column - cp rubout - ret z ;no column change if nulls - inc (hl) ;column = column + 1 - cp ' ' - ret nc ;return if graphic - ;not graphic, reset column position - dec (hl) ;column = column - 1 - ld a,(hl) - or a - ret z ;return if at zero - ;not at zero, may be backspace or end line - ld a,c ;character back to A - cp ctlh - jp nz,notbacksp - ;backspace character - dec (hl) ;column = column - 1 - ret - -notbacksp: ;not a backspace character, eol? - cp lf - ret nz ;return if not - ;end of line, column = 0 - ld (hl),0 ;column = 0 - ret - -ctlout: ;send C character with possible preceding up-arrow - ld a,c - call echoc ;cy if not graphic (or special case) - jp nc,tabout ;skip if graphic, tab, cr, lf, or ctlh - ;send preceding up arrow - push af - ld c,ctl - call conout ;up arrow - pop af - or 40h ;becomes graphic letter - ld c,a ;ready to print - ;(drop through to tabout) - -tabout: ;expand tabs to console - ld a,c - cp tab - jp nz,conout ;direct to conout if not - ;tab encountered, move to next tab position -tab0: ld c,' ' - call conout ;another blank - ld a,(column) - and 111b ;column mod 8 = 0 ? - jp nz,tab0 ;back for another if not - ret - -backup: ;back-up one screen position - call pctlh - ld c,' ' - call conoutf -; (drop through to pctlh) -pctlh: ;send ctlh to console without affecting column count - ld c,ctlh - jp conoutf -; ret -crlfp: ;print #, cr, lf for ctlx, ctlu, ctlr functions - ;then move to strtcol (starting column) - ld c,'#' - call conout - call crlf ;column = 0, move to position strtcol -crlfp0: ld a,(column) - ld hl,strtcol - cp (hl) - ret nc ;stop when column reaches strtcol - ld c,' ' - call conout ;print blank - jp crlfp0 - -crlf: ld c,cr ;carriage return line feed sequence - call conout - ld c,lf - jp conout -; ret -print: ld a,(bc) ;print message until M(BC) = '$' - cp '$' - ret z ;stop on $ - ;more to print - inc bc - push bc - ld c,a ;char to C - call tabout ;another character printed - pop bc - jp print - -read: ;read to info address (max length, current length, buffer) - ld a,(column) - ld (strtcol),a ;save start for ctl-x, ctl-h - ld hl,(info) - ld c,(hl) - inc hl - push hl - ld b,0 - ;B = current buffer length, - ;C = maximum buffer length, - ;HL= next to fill - 1 -readnx: ;read next character, BC, HL active - push bc - push hl ;blen, cmax, HL saved -readn0: call conin ;next char in A - and 7fh ;mask parity bit - pop hl - pop bc ;reactivate counters - cp cr - jp z,readen ;end of line? - cp lf - jp z,readen ;also end of line - cp ctlh - jp nz,noth ;backspace? - ;do we have any characters to back over? - ld a,b - or a - jp z,readnx - ;characters remain in buffer, backup one - dec b ;remove one character - ld a,(column) - ld (compcol),a ;col > 0 - ;compcol > 0 marks repeat as length compute - jp linelen ;uses same code as repeat - -noth: ;not a backspace - cp rubout - jp nz,notrub ;rubout char? - ;rubout encountered, rubout if possible - ld a,b - or a - jp z,readnx ;skip if len=0 - ;buffer has characters, resend last char - ld a,(hl) - dec b - dec hl ;A = last char - ;blen=blen-1, next to fill - 1 decremented - jp rdech1 ;act like this is an echo - -notrub: ;not a rubout character, check end line - cp ctle - jp nz,note ;physical end line? - ;yes, save active counters and force eol - push bc - push hl - call crlf - xor a - ld (strtcol),a ;start position = 00 - jp readn0 ;for another character - -note: ;not end of line, list toggle? - cp ctlp - jp nz,notp ;skip if not ctlp - ;list toggle - change parity - push hl ;save next to fill - 1 - ld hl,listcp ;HL=.listcp flag - ld a,1 - sub (hl) ;True-listcp - ld (hl),a ;listcp = not listcp - pop hl - jp readnx ;for another char - -notp: ;not a ctlp, line delete? - cp ctlx - jp nz,notx - pop hl ;discard start position - ;loop while column > strtcol -backx: ld a,(strtcol) - ld hl,column - cp (hl) - jp nc,read ;start again - dec (hl) ;column = column - 1 - call backup ;one position - jp backx - -notx: ;not a control x, control u? - ;not control-X, control-U? - cp ctlu - jp nz,notu ;skip if not - ;delete line (ctlu) - call crlfp ;physical eol - pop hl ;discard starting position - jp read ;to start all over - -notu: ;not line delete, repeat line? - cp ctlr - jp nz,notr -linelen: ;repeat line, or compute line len (ctlh) - ;if compcol > 0 - push bc - call crlfp ;save line length - pop bc - pop hl - push hl - push bc - ;bcur, cmax active, beginning buff at HL -rep0: ld a,b - or a - jp z,rep1 ;count len to 00 - inc hl - ld c,(hl) ;next to print - dec b - push bc - push hl ;count length down - call ctlout ;character echoed - pop hl - pop bc ;recall remaining count - jp rep0 ;for the next character - -rep1: ;end of repeat, recall lengths - ;original BC still remains pushed - push hl ;save next to fill - ld a,(compcol) - or a ;>0 if computing length - jp z,readn0 ;for another char if so - ;column position computed for ctlh - ld hl,column - sub (hl) ;diff > 0 - ld (compcol),a ;count down below - ;move back compcol-column spaces -backsp: ;move back one more space - call backup ;one space - ld hl,compcol - dec (hl) - jp nz,backsp - jp readn0 ;for next character - -notr: ;not a ctlr, place into buffer -rdecho: inc hl - ld (hl),a ;character filled to mem - inc b ;blen = blen + 1 -rdech1: ;look for a random control character - push bc - push hl ;active values saved - ld c,a ;ready to print - call ctlout ;may be up-arrow C - pop hl - pop bc - ld a,(hl) ;recall char - cp ctlc ;set flags for reboot test - ld a,b ;move length to A - jp nz,notc ;skip if not a control c - cp 1 ;control C, must be length 1 - jp z,reboot ;reboot if blen = 1 - ;length not one, so skip reboot -notc: ;not reboot, are we at end of buffer? - cp c - jp c,readnx ;go for another if not -readen: ;end of read operation, store blen - pop hl - ld (hl),b ;M(current len) = B - ld c,cr - jp conout ;return carriage -; ret -func1: ;return console character with echo - call conech - jp sta$ret - -func2 equ tabout - ;write console character with tab expansion - -func3: ;return reader character - call readerf - jp sta$ret - -;func4: equated to punchf - ;write punch character - -;func5: equated to listf - ;write list character - ;write to list device - -func6: ;direct console i/o - read if 0ffh - ld a,c - inc a - jp z,dirinp ;0ffh => 00h, means input mode - inc a - jp z,constf ;0feH in C for status - ;direct output function - jp conoutf - -dirinp: call constf ;status check - or a - jp z,retmon ;skip, return 00 if not ready - ;character is ready, get it - call coninf ;to A - jp sta$ret - -func7: ;return io byte - ld a,(ioloc) - jp sta$ret - -func8: ;set i/o byte - ld hl,ioloc - ld (hl),c - ret ;jmp goback - -func9: ;write line until $ encountered - ex de,hl ;was lhld info - ld c,l - ld b,h ;BC=string address - jp print ;out to console - -func10 equ read - ;read a buffered console line - -func11: ;check console status - call conbrk - ;(drop through to sta$ret) -sta$ret: ;store the A register to aret - ld (aret),a -func$ret: - ret ;jmp goback (pop stack for non cp/m functions) - -setlret1: ;set lret = 1 - ld a,1 - jp sta$ret - - - -; data areas - -compcol: - .db 0 ;true if computing column position - -strtcol: - .db 0 ;starting column position after read - -column: .db 0 ;column position -listcp: .db 0 ;listing toggle -kbchar: .db 0 ;initial key char = 00 -entsp: .ds 2 ;entry stack pointer - .ds ssize*2 ;stack size - -lstack: - -; end of Basic I/O System - -;***************************************************************** -;***************************************************************** - -; common values shared between bdosi and bdos -usrcode: - .db 0 ;current user number -curdsk: .db 0 ;current disk number -info: .ds 2 ;information address -aret: .ds 2 ;address value to return -lret .equ aret ;low(aret) - -;***************************************************************** -;***************************************************************** -;** ** -;** B a s i c D i s k O p e r a t i n g S y s t e m ** -;** ** -;***************************************************************** -;***************************************************************** - -;;dvers equ 22h ;version 2.2 -dvers = 0x22 - -; module addresses - -; literal constants - -;;true equ 0ffh ;constant true -true = 0xff - -;;false equ 000h ;constant false -false = 0x00 - -;;enddir equ 0ffffh ;end of directory -enddir = 0xffff - -;;byte equ 1 ;number of bytes for "byte" type -byte = 1 - -;;word equ 2 ;number of bytes for "word" type -word = 2 - -; fixed addresses in low memory - -;;tfcb equ 005ch ;default fcb location -tfcb = 0x5c - -;;tbuff equ 0080h ;default buffer location -tbuff = 0x80 - -; fixed addresses referenced in bios module are -; pererr (0009), selerr (000c), roderr (000f) - -; error message handlers - -;per$error: ;report permanent error to user -; ld hl,pererr -; jp goerr - -;rod$error: ;report read/only disk error -; ld hl,roderr -; jp goerr - -;rof$error: ;report read/only file error -; ld hl,roferr -; jp goerr - -sel$error: ;report select error - ld hl,selerr - - -goerr: ;HL = .errorhandler, call subroutine - ld e,(hl) - inc hl - ld d,(hl) ;address of routine in DE - ex de,hl - jp (hl) ;to subroutine - - - -; local subroutines for bios interface - -move: ;move data length of length C from source DE to - ;destination given by HL - inc c ;in case it is zero -move0: dec c - ret z ;more to move - ld a,(de) - ld (hl),a ;one byte moved - inc de - inc hl ;to next byte - jp move0 - -selectdisk: ;select the disk drive given by curdsk, and fill - ;the base addresses curtrka - alloca, then fill - ;the values of the disk parameter block - ld a,(curdsk) - ld c,a ;current disk# to c - ;lsb of e = 0 if not yet logged - in - call seldskf ;HL filled by call - ;HL = 0000 if error, otherwise disk headers - ld a,h - or l - ret z ;return with 0000 in HL and z flag - ;disk header block address in hl - ld e,(hl) - inc hl - ld d,(hl) - inc hl ;DE=.tran - ld (cdrmaxa),hl - inc hl - inc hl ;.cdrmax - ld (curtrka),hl - inc hl - inc hl ;HL=.currec - ld (curreca),hl - inc hl - inc hl ;HL=.buffa - ;DE still contains .tran - ex de,hl - ld (tranv),hl ;.tran vector - ld hl,buffa ;DE= source for move, HL=dest - ld c,addlist - call move ;addlist filled - ;now fill the disk parameter block - ld hl,(dpbaddr) - ex de,hl ;DE is source - ld hl,sectpt ;HL is destination - ld c,dpblist - call move ;data filled - ;now set single/double map mode - ld hl,(maxall) ;largest allocation number - ld a,h ;00 indicates < 255 - ld hl,single - ld (hl),true ;assume a=00 - or a - jp z,retselect - ;high order of maxall not zero, use double dm - ld (hl),false -retselect: - ld a,true - or a - ret ;select disk function ok - -home: ;move to home position, then offset to start of dir - call homef ;move to track 00, sector 00 reference - ;lxi h,offset ;mov c,m ;inx h ;mov b,m ;call settrkf - ;first directory position selected - xor a ;constant zero to accumulator - ld hl,(curtrka) - ld (hl),a - inc hl - ld (hl),a ;curtrk=0000 - ld hl,(curreca) - ld (hl),a - inc hl - ld (hl),a ;currec=0000 - ;curtrk, currec both set to 0000 - ret - -rdbuff: ;read buffer and check condition - call readf ;current drive, track, sector, dma - jp diocomp ;check for i/o errors - -wrbuff: ;write buffer and check condition - ;write type (wrtype) is in register C - ;wrtype = 0 => normal write operation - ;wrtype = 1 => directory write operation - ;wrtype = 2 => start of new block - call writef ;current drive, track, sector, dma -diocomp: ;check for disk errors - or a - ret z - ld hl,pererr - jp goerr - -seek$dir: ;seek the record containing the current dir entry - ld hl,(dcnt) ;directory counter to HL - ld c,dskshf - call hlrotr ;value to HL - ld (arecord),hl - ld (drec),hl ;ready for seek -; jp seek -; ret - - -seek: ;seek the track given by arecord (actual record) - ;local equates for registers - ;load the registers from memory - ld hl,arecord - ld c,(hl) - inc hl - ld b,(hl) - ld hl,(curreca) - ld e,(hl) - inc hl - ld d,(hl) - ld hl,(curtrka) - ld a,(hl) - inc hl - ld h,(hl) - ld l,a - ;loop while arecord < currec -seek0: ld a,c - sub e - ld a,b - sbc a,d - jp nc,seek1 ;skip if arecord >= currec - ;currec = currec - sectpt - push hl - ld hl,(sectpt) - ld a,e - sub l - ld e,a - ld a,d - sbc a,h - ld d,a - pop hl - ;curtrk = curtrk - 1 - dec hl - jp seek0 ;for another try - -seek1: ;look while arecord >= (t:=currec + sectpt) - push hl - ld hl,(sectpt) - add hl,de ;HL = currec+sectpt - jp c,seek2 ;can be > FFFFH - ld a,c - sub l - ld a,b - sbc a,h - jp c,seek2 ;skip if t > arecord - ;currec = t - ex de,hl - ;curtrk = curtrk + 1 - pop hl - inc hl - jp seek1 ;for another try - -seek2: pop hl - ;arrive here with updated values in each register - push bc - push de - push hl ;to stack for later - ;stack contains (lowest) BC=arecord, DE=currec, HL=curtrk - ex de,hl - ld hl,(offset) - add hl,de ;HL = curtrk+offset - ld b,h - ld c,l - call settrkf ;track set up - ;note that BC - curtrk is difference to move in bios - pop de ;recall curtrk - ld hl,(curtrka) - ld (hl),e - inc hl - ld (hl),d ;curtrk updated - ;now compute sector as arecord-currec - pop de ;recall currec - ld hl,(curreca) - ld (hl),e - inc hl - ld (hl),d - pop bc ;BC=arecord, DE=currec - ld a,c - sub e - ld c,a - ld a,b - sbc a,d - ld b,a - ld hl,(tranv) - ex de,hl ;BC=sector#, DE=.tran - call sectran ;HL = tran(sector) - ld c,l - ld b,h ;BC = tran(sector) - jp setsecf ;sector selected -; ret - -; file control block (fcb) constants -empty equ 0e5h ;empty directory entry -lstrec equ 127 ;last record# in extent -recsiz equ 128 ;record size -fcblen equ 32 ;file control block size -dirrec equ recsiz/fcblen ;directory elts / record -dskshf equ 2 ;log2(dirrec) -dskmsk equ dirrec-1 -fcbshf equ 5 ;log2(fcblen) - -extnum equ 12 ;extent number field -maxext equ 31 ;largest extent number -ubytes equ 13 ;unfilled bytes field -modnum equ 14 ;data module number -maxmod equ 15 ;largest module number -fwfmsk equ 80h ;file write flag is high order modnum -namlen equ 15 ;name length -reccnt equ 15 ;record count field -dskmap equ 16 ;disk map field -lstfcb equ fcblen-1 -nxtrec equ fcblen -ranrec equ nxtrec+1 ;random record field (2 bytes) - -; reserved file indicators -rofile equ 9 ;high order of first type char -invis equ 10 ;invisible file in dir command -; equ 11 ;reserved - -; utility functions for file access - -dm$position: ;compute disk map position for vrecord to HL - ld hl,blkshf - ld c,(hl) ;shift count to C - ld a,(vrecord) ;current virtual record to A -dmpos0: or a - rra - dec c - jp nz,dmpos0 - ;A = shr(vrecord,blkshf) = vrecord/2**(sect/block) - ld b,a ;save it for later addition - ld a,8 - sub (hl) ;8-blkshf to accumulator - ld c,a ;extent shift count in register c - ld a,(extval) ;extent value ani extmsk -dmpos1: - ;blkshf = 3,4,5,6,7, C=5,4,3,2,1 - ;shift is 4,3,2,1,0 - dec c - jp z,dmpos2 - or a - rla - jp dmpos1 - -dmpos2: ;arrive here with A = shl(ext and extmsk,7-blkshf) - add a,b ;add the previous shr(vrecord,blkshf) value - ;A is one of the following values, depending upon alloc - ;bks blkshf - ;1k 3 v/8 + extval * 16 - ;2k 4 v/16+ extval * 8 - ;4k 5 v/32+ extval * 4 - ;8k 6 v/64+ extval * 2 - ;16k 7 v/128+extval * 1 - ret ;with dm$position in A - -getdm: ;return disk map value from position given by BC - ld hl,(info) ;base address of file control block - ld de,dskmap - add hl,de ;HL =.diskmap - add hl,bc ;index by a single byte value - ld a,(single) ;single byte/map entry? - or a - jp z,getdmd ;get disk map single byte - ld l,(hl) - ld h,0 - ret ;with HL=00bb -getdmd: - add hl,bc ;HL=.fcb(dm+i*2) - ;double precision value returned - ld e,(hl) - inc hl - ld d,(hl) - ex de,hl - ret - -index: ;compute disk block number from current fcb - call dm$position ;0...15 in register A - ld c,a - ld b,0 - call getdm ;value to HL - ld (arecord),hl - ret - -allocated: ;called following index to see if block allocated - ld hl,(arecord) - ld a,l - or h - ret - -atran: ;compute actual record address, assuming index called - ld a,(blkshf) ;shift count to reg A - ld hl,(arecord) -atran0: add hl,hl - dec a - jp nz,atran0 ;shl(arecord,blkshf) - ld (arecord1),hl ;save shifted block # - ld a,(blkmsk) - ld c,a ;mask value to C - ld a,(vrecord) - and c ;masked value in A - or l - ld l,a ;to HL - ld (arecord),hl ;arecord=HL or (vrecord and blkmsk) - ret - -getexta: ;get current extent field address to A - ld hl,(info) - ld de,extnum - add hl,de ;HL=.fcb(extnum) - ret - -getfcba: ;compute reccnt and nxtrec addresses for get/setfcb - ld hl,(info) - ld de,reccnt - add hl,de - ex de,hl ;DE=.fcb(reccnt) - ld hl,nxtrec-reccnt - add hl,de ;HL=.fcb(nxtrec) - ret - -getfcb: ;set variables from currently addressed fcb - call getfcba ;addresses in DE, HL - ld a,(hl) - ld (vrecord),a ;vrecord=fcb(nxtrec) - ex de,hl - ld a,(hl) - ld (rcount),a ;rcount=fcb(reccnt) - call getexta ;HL=.fcb(extnum) - ld a,(extmsk) ;extent mask to a - and (hl) ;fcb(extnum) and extmsk - ld (extval),a - ret - -setfcb: ;place values back into current fcb - call getfcba ;addresses to DE, HL - ld a,(seqio) - cp 02 - jp nz,setfcb1 - xor a ;check ranfill -setfcb1: - ld c,a ;=1 if sequential i/o - ld a,(vrecord) - add a,c - ld (hl),a ;fcb(nxtrec)=vrecord+seqio - ex de,hl - ld a,(rcount) - ld (hl),a ;fcb(reccnt)=rcount - ret - -hlrotr: ;hl rotate right by amount C - inc c ;in case zero -hlrotr0: - dec c - ret z ;return when zero - ld a,h - or a - rra - ld h,a ;high byte - ld a,l - rra - ld l,a ;low byte - jp hlrotr0 - -compute$cs: ;compute checksum for current directory buffer - ld c,recsiz ;size of directory buffer - ld hl,(buffa) ;current directory buffer - xor a ;clear checksum value -computecs0: - add a,(hl) - inc hl - dec c ;cs=cs+buff(recsiz-C) - jp nz,computecs0 - ret ;with checksum in A - -hlrotl: ;rotate the mask in HL by amount in C - inc c ;may be zero -hlrotl0: - dec c - ret z ;return if zero - add hl,hl - jp hlrotl0 - -set$cdisk: ;set a "1" value in curdsk position of BC - push bc ;save input parameter - ld a,(curdsk) - ld c,a ;ready parameter for shift - ld hl,1 ;number to shift - call hlrotl ;HL = mask to integrate - pop bc ;original mask - ld a,c - or l - ld l,a - ld a,b - or h - ld h,a ;HL = mask or rol(1,curdsk) - ret - -nowrite: ;return true if dir checksum difference occurred - ld hl,(rodsk) - ld a,(curdsk) - ld c,a - call hlrotr - ld a,l - and 1b - ret ;non zero if nowrite - -set$ro: ;set current disk to read only - ld hl,rodsk - ld c,(hl) - inc hl - ld b,(hl) - call set$cdisk ;sets bit to 1 - ld (rodsk),hl - ;high water mark in directory goes to max - ld hl,(dirmax) - inc hl - ex de,hl ;DE = directory max - ld hl,(cdrmaxa) ;HL = .cdrmax - ld (hl),e - inc hl - ld (hl),d ;cdrmax = dirmax - ret - -check$rodir: ;check current directory element for read/only status - call getdptra ;address of element - -check$rofile: ;check current buff(dptr) or fcb(0) for r/o status - ld de,rofile - add hl,de ;offset to ro bit - ld a,(hl) - rla - ret nc ;return if not set - ld hl,roferr - jp goerr -; jp rof$error ;exit to read only disk message - - -check$write: ;check for write protected disk - call nowrite - ret z ;ok to write if not rodsk - ld hl,roderr - jp goerr -; jp rod$error ;read only disk error - -getdptra: ;compute the address of a directory element at - ;positon dptr in the buffer - ld hl,(buffa) - ld a,(dptr) -addh: ;HL = HL + A - add a,l - ld l,a - ret nc - ;overflow to H - inc h - ret - - -getmodnum: ;compute the address of the module number - ;bring module number to accumulator - ;(high order bit is fwf (file write flag) - ld hl,(info) - ld de,modnum - add hl,de ;HL=.fcb(modnum) - ld a,(hl) - ret ;A=fcb(modnum) - -clrmodnum: ;clear the module number field for user open/make - call getmodnum - ld (hl),0 ;fcb(modnum)=0 - ret - -setfwf: call getmodnum ;HL=.fcb(modnum), A=fcb(modnum) - ;set fwf (file write flag) to "1" - or fwfmsk - ld (hl),a ;fcb(modnum)=fcb(modnum) or 80h - ;also returns non zero in accumulator - ret - - -compcdr: ;return cy if cdrmax > dcnt - ld hl,(dcnt) - ex de,hl ;DE = directory counter - ld hl,(cdrmaxa) ;HL=.cdrmax - ld a,e - sub (hl) ;low(dcnt) - low(cdrmax) - inc hl ;HL = .cdrmax+1 - ld a,d - sbc a,(hl) ;hig(dcnt) - hig(cdrmax) - ;condition dcnt - cdrmax produces cy if cdrmax>dcnt - ret - -setcdr: ;if not (cdrmax > dcnt) then cdrmax = dcnt+1 - call compcdr - ret c ;return if cdrmax > dcnt - ;otherwise, HL = .cdrmax+1, DE = dcnt - inc de - ld (hl),d - dec hl - ld (hl),e - ret - -subdh: ;compute HL = DE - HL - ld a,e - sub l - ld l,a - ld a,d - sbc a,h - ld h,a - ret - -newchecksum: - ld c,true ;drop through to compute new checksum -checksum: ;compute current checksum record and update the - ;directory element if C=true, or check for = if not - ;drec < chksiz? - ld hl,(drec) - ex de,hl - ld hl,(chksiz) - call subdh ;DE-HL - ret nc ;skip checksum if past checksum vector size - ;drec < chksiz, so continue - push bc ;save init flag - call compute$cs ;check sum value to A - ld hl,(checka) ;address of check sum vector - ex de,hl - ld hl,(drec) ;value of drec - add hl,de ;HL = .check(drec) - pop bc ;recall true=0ffh or false=00 to C - inc c ;0ffh produces zero flag - jp z,initial$cs - ;not initializing, compare - cp (hl) ;compute$cs=check(drec)? - ret z ;no message if ok - ;checksum error, are we beyond - ;the end of the disk? - call compcdr - ret nc ;no message if so - call set$ro ;read/only disk set - ret - -initial$cs: ;initializing the checksum - ld (hl),a - ret - - -wrdir: ;write the current directory entry, set checksum - call newchecksum ;initialize entry - call setdir ;directory dma - ld c,1 ;indicates a write directory operation - call wrbuff ;write the buffer - jp setdata ;to data dma address -; ret -rd$dir: ;read a directory entry into the directory buffer - call setdir ;directory dma - call rdbuff ;directory record loaded - ;jmp setdata to data dma address -; ret -setdata: ;set data dma address - ld hl,dmaad - jp setdma ;to complete the call - -setdir: ;set directory dma address - ld hl,buffa ;jmp setdma to complete call - -setdma: ;HL=.dma address to set (i.e., buffa or dmaad) - ld c,(hl) - inc hl - ld b,(hl) ;parameter ready - jp setdmaf - -dir$to$user: ;copy the directory entry to the user buffer - ;after call to search or searchn by user code - ld hl,(buffa) - ex de,hl ;source is directory buffer - ld hl,(dmaad) ;destination is user dma address - ld c,recsiz ;copy entire record - jp move -; ret - -end$of$dir: ;return zero flag if at end of directory, non zero - ;if not at end (end of dir if dcnt = 0ffffh) - ld hl,dcnt - ld a,(hl) ;may be 0ffh - inc hl - cp (hl) ;low(dcnt) = high(dcnt)? - ret nz ;non zero returned if different - ;high and low the same, = 0ffh? - inc a ;0ffh becomes 00 if so - ret - -set$end$dir: ;set dcnt to the end of the directory - ld hl,enddir - ld (dcnt),hl - ret - -read$dir: ;read next directory entry, with C=true if initializing - ld hl,(dirmax) - ex de,hl ;in preparation for subtract - ld hl,(dcnt) - inc hl - ld (dcnt),hl ;dcnt=dcnt+1 - ;continue while dirmax >= dcnt (dirmax-dcnt no cy) - call subdh ;DE-HL - jp nc,read$dir0 - ;yes, set dcnt to end of directory - jp set$end$dir -; ret - -read$dir0: ;not at end of directory, seek next element - ;initialization flag is in C - ld a,(dcnt) - and dskmsk ;low(dcnt) and dskmsk - ld b,fcbshf ;to multiply by fcb size -read$dir1: - add a,a - dec b - jp nz,read$dir1 - ;A = (low(dcnt) and dskmsk) shl fcbshf - ld (dptr),a ;ready for next dir operation - or a - ret nz ;return if not a new record - push bc ;save initialization flag C - call seek$dir ;seek proper record - call rd$dir ;read the directory record - pop bc ;recall initialization flag - jp checksum ;checksum the directory elt -; ret - - -getallocbit: ;given allocation vector position BC, return with byte - ;containing BC shifted so that the least significant - ;bit is in the low order accumulator position. HL is - ;the address of the byte for possible replacement in - ;memory upon return, and D contains the number of shifts - ;required to place the returned value back into position - ld a,c - -;; and 111b - and 0b00000111 - - inc a - ld e,a - ld d,a - ;d and e both contain the number of bit positions to shift - ld a,c - rrca - rrca - rrca - -; and 11111b - and 0b00011111 - - ld c,a ;C shr 3 to C - ld a,b - add a,a - add a,a - add a,a - add a,a - add a,a ;B shl 5 - or c - ld c,a ;bbbccccc to C - ld a,b - rrca - rrca - rrca - -;; and 11111b - and 0b00011111 - - ld b,a ;BC shr 3 to BC - ld hl,(alloca) ;base address of allocation vector - add hl,bc - ld a,(hl) ;byte to A, hl = .alloc(BC shr 3) - ;now move the bit to the low order position of A -rotl: rlca - dec e - jp nz,rotl - ret - - -set$alloc$bit: ;BC is the bit position of ALLOC to set or reset. The - ;value of the bit is in register E. - push de - call getallocbit ;shifted val A, count in D - -;; and 11111110b ;mask low bit to zero (may be set) - and 0b11111110 - - or c ;low bit of C is masked into A -; jp rotr ;to rotate back into proper position -; ret -rotr: - ;byte value from ALLOC is in register A, with shift count - ;in register C (to place bit back into position), and - ;target ALLOC position in registers HL, rotate and replace - rrca - dec d - jp nz,rotr ;back into position - ld (hl),a ;back to ALLOC - ret - -scandm: ;scan the disk map addressed by dptr for non-zero - ;entries, the allocation vector entry corresponding - ;to a non-zero entry is set to the value of C (0,1) - call getdptra ;HL = buffa + dptr - ;HL addresses the beginning of the directory entry - ld de,dskmap - add hl,de ;hl now addresses the disk map - push bc ;save the 0/1 bit to set - ld c,fcblen-dskmap+1;size of single byte disk map + 1 -scandm0: ;loop once for each disk map entry - pop de ;recall bit parity - dec c - ret z ;all done scanning? - ;no, get next entry for scan - push de ;replace bit parity - ld a,(single) - or a - jp z,scandm1 - ;single byte scan operation - push bc ;save counter - push hl ;save map address - ld c,(hl) - ld b,0 ;BC=block# - jp scandm2 - -scandm1: ;double byte scan operation - dec c ;count for double byte - push bc ;save counter - ld c,(hl) - inc hl - ld b,(hl) ;BC=block# - push hl ;save map address -scandm2: ;arrive here with BC=block#, E=0/1 - ld a,c - or b ;skip if = 0000 - jp z,scanm3 - ld hl,(maxall) ;check invalid index - ld a,l - sub c - ld a,h - sbc a,b ;maxall - block# - call nc,set$alloc$bit - ;bit set to 0/1 -scanm3: pop hl - inc hl ;to next bit position - pop bc ;recall counter - jp scandm0 ;for another item - -initialize: ;initialize the current disk - ;lret = false ;set to true if $ file exists - ;compute the length of the allocation vector - 2 - ld hl,(maxall) - ld c,3 ;perform maxall/8 - ;number of bytes in alloc vector is (maxall/8)+1 - call hlrotr - inc hl ;HL = maxall/8+1 - ld b,h - ld c,l ;count down BC til zero - ld hl,(alloca) ;base of allocation vector - ;fill the allocation vector with zeros -initial0: - ld (hl),0 - inc hl ;alloc(i)=0 - dec bc ;count length down - ld a,b - or c - jp nz,initial0 - ;set the reserved space for the directory - ld hl,(dirblk) - ex de,hl - ld hl,(alloca) ;HL=.alloc() - ld (hl),e - inc hl - ld (hl),d ;sets reserved directory blks - ;allocation vector initialized, home disk - call home - ;cdrmax = 3 (scans at least one directory record) - ld hl,(cdrmaxa) - ld (hl),3 - inc hl - ld (hl),0 - ;cdrmax = 0000 - call set$end$dir ;dcnt = enddir - ;read directory entries and check for allocated storage -initial2: - ld c,true - call read$dir - call end$of$dir - ret z ;return if end of directory - ;not end of directory, valid entry? - call getdptra ;HL = buffa + dptr - ld a,empty - cp (hl) - jp z,initial2 ;go get another item - ;not empty, user code the same? - ld a,(usrcode) - cp (hl) - jp nz,pdollar - ;same user code, check for '$' submit - inc hl - ld a,(hl) ;first character - sub '$' ;dollar file? - jp nz,pdollar - ;dollar file found, mark in lret - dec a - ld (lret),a ;lret = 255 -pdollar: ;now scan the disk map for allocated blocks - ld c,1 ;set to allocated - call scandm - call setcdr ;set cdrmax to dcnt - jp initial2 ;for another entry - -copy$dirloc: ;copy directory location to lret following - ;delete, rename, ... ops - ld a,(dirloc) - jp sta$ret -; ret - -compext: ;compare extent# in A with that in C, return nonzero - ;if they do not match - push bc ;save C's original value - push af - ld a,(extmsk) - cpl - ld b,a - ;B has negated form of extent mask - ld a,c - and b - ld c,a ;low bits removed from C - pop af - and b ;low bits removed from A - sub c - and maxext ;set flags - pop bc ;restore original values - ret - -search: ;search for directory element of length C at info - -;; ld a,0ffh - ld a,0xff - - ld (dirloc),a ;changed if actually found - ld hl,searchl - ld (hl),c ;searchl = C - ld hl,(info) - ld (searcha),hl ;searcha = info - call set$end$dir ;dcnt = enddir - call home ;to start at the beginning - ;(drop through to searchn) - -searchn: ;search for the next directory element, assuming - ;a previous call on search which sets searcha and - ;searchl - ld c,false - call read$dir ;read next dir element - call end$of$dir - jp z,search$fin ;skip to end if so - ;not end of directory, scan for match - ld hl,(searcha) - ex de,hl ;DE=beginning of user fcb - ld a,(de) ;first character - cp empty ;keep scanning if empty - jp z,searchnext - ;not empty, may be end of logical directory - push de ;save search address - call compcdr ;past logical end? - pop de ;recall address - jp nc,search$fin ;artificial stop -searchnext: - call getdptra ;HL = buffa+dptr - ld a,(searchl) - ld c,a ;length of search to c - ld b,0 ;b counts up, c counts down -searchloop: - ld a,c - or a - jp z,endsearch - ld a,(de) - cp '?' - jp z,searchok ;? matches all - ;scan next character if not ubytes - ld a,b - cp ubytes - jp z,searchok - ;not the ubytes field, extent field? - cp extnum ;may be extent field - ld a,(de) ;fcb character - jp z,searchext ;skip to search extent - sub (hl) - and 7fh ;mask-out flags/extent modulus - jp nz,searchn ;skip if not matched - jp searchok ;matched character - -searchext: ;A has fcb character - ;attempt an extent # match - push bc ;save counters - ld c,(hl) ;directory character to c - call compext ;compare user/dir char - pop bc ;recall counters - jp nz,searchn ;skip if no match -searchok: ;current character matches - inc de - inc hl - inc b - dec c - jp searchloop - -endsearch: ;entire name matches, return dir position - ld a,(dcnt) - and dskmsk - ld (lret),a - ;lret = low(dcnt) and 11b - ld hl,dirloc - ld a,(hl) - rla - ret nc ;dirloc=0ffh? - ;yes, change it to 0 to mark as found - xor a - ld (hl),a ;dirloc=0 - ret - -search$fin: ;end of directory, or empty name - call set$end$dir ;may be artifical end - ld a,255 - jp sta$ret - -delete: ;delete the currently addressed file - call check$write ;write protected? - ld c,extnum - call search ;search through file type -delete0: - ;loop while directory matches - call end$of$dir - ret z ;stop if end - ;set each non zero disk map entry to 0 - ;in the allocation vector - ;may be r/o file - call check$rodir ;ro disk error if found - call getdptra ;HL=.buff(dptr) - ld (hl),empty - ld c,0 - call scandm ;alloc elts set to 0 - call wrdir ;write the directory - call searchn ;to next element - jp delete0 ;for another record - -get$block: ;given allocation vector position BC, find the zero bit - ;closest to this position by searching left and right. - ;if found, set the bit to one and return the bit position - ;in hl. if not found (i.e., we pass 0 on the left, or - ;maxall on the right), return 0000 in hl - ld d,b - ld e,c ;copy of starting position to de -lefttst: - ld a,c - or b - jp z,righttst ;skip if left=0000 - ;left not at position zero, bit zero? - dec bc - push de - push bc ;left,right pushed - call getallocbit - rra - jp nc,retblock ;return block number if zero - ;bit is one, so try the right - pop bc - pop de ;left, right restored -righttst: - ld hl,(maxall) ;value of maximum allocation# - ld a,e - sub l - ld a,d - sbc a,h ;right=maxall? - jp nc,retblock0 ;return block 0000 if so - inc de - push bc - push de ;left, right pushed - ld b,d - ld c,e ;ready right for call - call getallocbit - rra - jp nc,retblock ;return block number if zero - pop de - pop bc ;restore left and right pointers - jp lefttst ;for another attempt -retblock: - rla - inc a ;bit back into position and set to 1 - ;d contains the number of shifts required to reposition - call rotr ;move bit back to position and store - pop hl - pop de ;HL returned value, DE discarded - ret - -retblock0: ;cannot find an available bit, return 0000 - ld a,c - or b - jp nz,lefttst ;also at beginning - ld hl,0000h - ret - -copy$fcb: ;copy the entire file control block - ld c,0 - ld e,fcblen ;start at 0, to fcblen-1 -; jp copy$dir - -copy$dir: ;copy fcb information starting at C for E bytes - ;into the currently addressed directory entry - push de ;save length for later - ld b,0 ;double index to BC - ld hl,(info) ;HL = source for data - add hl,bc - ex de,hl ;DE=.fcb(C), source for copy - call getdptra ;HL=.buff(dptr), destination - pop bc ;DE=source, HL=dest, C=length - call move ;data moved -seek$copy: ;enter from close to seek and copy current element - call seek$dir ;to the directory element - jp wrdir ;write the directory element -; ret -rename: ;rename the file described by the first half of - ;the currently addressed file control block. the - ;new name is contained in the last half of the - ;currently addressed file conrol block. the file - ;name and type are changed, but the reel number - ;is ignored. the user number is identical - call check$write ;may be write protected - ;search up to the extent field - ld c,extnum - call search - ;copy position 0 - ld hl,(info) - ld a,(hl) ;HL=.fcb(0), A=fcb(0) - ld de,dskmap - add hl,de ;HL=.fcb(dskmap) - ld (hl),a ;fcb(dskmap)=fcb(0) - ;assume the same disk drive for new named file -rename0: - call end$of$dir - ret z ;stop at end of dir - ;not end of directory, rename next element - call check$rodir ;may be read-only file - ld c,dskmap - ld e,extnum - call copy$dir - ;element renamed, move to next - call searchn - jp rename0 - -indicators: ;set file indicators for current fcb - ld c,extnum - call search ;through file type -indic0: call end$of$dir - ret z ;stop at end of dir - ;not end of directory, continue to change - ld c,0 - ld e,extnum ;copy name - call copy$dir - call searchn - jp indic0 - -open: ;search for the directory entry, copy to fcb - ld c,namlen - call search - call end$of$dir - ret z ;return with lret=255 if end - ;not end of directory, copy fcb information -open$copy: ;(referenced below to copy fcb info) - call getexta - ld a,(hl) - push af - push hl ;save extent# - call getdptra - ex de,hl ;DE = .buff(dptr) - ld hl,(info) ;HL=.fcb(0) - ld c,nxtrec ;length of move operation - push de ;save .buff(dptr) - call move ;from .buff(dptr) to .fcb(0) - ;note that entire fcb is copied, including indicators - call setfwf ;sets file write flag - pop de - ld hl,extnum - add hl,de ;HL=.buff(dptr+extnum) - ld c,(hl) ;C = directory extent number - ld hl,reccnt - add hl,de ;HL=.buff(dptr+reccnt) - ld b,(hl) ;B holds directory record count - pop hl - pop af - ld (hl),a ;restore extent number - ;HL = .user extent#, B = dir rec cnt, C = dir extent# - ;if user ext < dir ext then user := 128 records - ;if user ext = dir ext then user := dir records - ;if user ext > dir ext then user := 0 records - ld a,c - cp (hl) - ld a,b ;ready dir reccnt - jp z,open$rcnt ;if same, user gets dir reccnt - ld a,0 - jp c,open$rcnt ;user is larger - ld a,128 ;directory is larger -open$rcnt: ;A has record count to fill - ld hl,(info) - ld de,reccnt - add hl,de - ld (hl),a - ret - -mergezero: ;HL = .fcb1(i), DE = .fcb2(i), - ;if fcb1(i) = 0 then fcb1(i) := fcb2(i) - ld a,(hl) - inc hl - or (hl) - dec hl - ret nz ;return if = 0000 - ld a,(de) - ld (hl),a - inc de - inc hl ;low byte copied - ld a,(de) - ld (hl),a - dec de - dec hl ;back to input form - ret - -close: ;locate the directory element and re-write it - xor a - ld (lret),a - ld (dcnt),a - ld (dcnt+1),a - call nowrite - ret nz ;skip close if r/o disk - ;check file write flag - 0 indicates written - call getmodnum ;fcb(modnum) in A - and fwfmsk - ret nz ;return if bit remains set - ld c,namlen - call search ;locate file - call end$of$dir - ret z ;return if not found - ;merge the disk map at info with that at buff(dptr) - ld bc,dskmap - call getdptra - add hl,bc - ex de,hl ;DE is .buff(dptr+16) - ld hl,(info) - add hl,bc ;DE=.buff(dptr+16), HL=.fcb(16) - ld c,fcblen-dskmap;length of single byte dm -merge0: ld a,(single) - or a - jp z,merged ;skip to double - ;this is a single byte map - ;if fcb(i) = 0 then fcb(i) = buff(i) - ;if buff(i) = 0 then buff(i) = fcb(i) - ;if fcb(i) <> buff(i) then error - ld a,(hl) - or a - ld a,(de) - jp nz,fcbnzero - ;fcb(i) = 0 - ld (hl),a ;fcb(i) = buff(i) -fcbnzero: - or a - jp nz,buffnzero - ;buff(i) = 0 - ld a,(hl) - ld (de),a ;buff(i)=fcb(i) -buffnzero: - cp (hl) - jp nz,mergerr ;fcb(i) = buff(i)? - jp dmset ;if merge ok - -merged: ;this is a double byte merge operation - call mergezero ;buff = fcb if buff 0000 - ex de,hl - call mergezero - ex de,hl ;fcb = buff if fcb 0000 - ;they should be identical at this point - ld a,(de) - cp (hl) - jp nz,mergerr ;low same? - inc de - inc hl ;to high byte - ld a,(de) - cp (hl) - jp nz,mergerr ;high same? - ;merge operation ok for this pair - dec c ;extra count for double byte -dmset: inc de - inc hl ;to next byte position - dec c - jp nz,merge0 ;for more - ;end of disk map merge, check record count - ;DE = .buff(dptr)+32, HL = .fcb(32) - ld bc,-(fcblen-extnum) - add hl,bc - ex de,hl - add hl,bc - ;DE = .fcb(extnum), HL = .buff(dptr+extnum) - ld a,(de) ;current user extent number - ;if fcb(ext) >= buff(fcb) then - ;buff(ext) := fcb(ext), buff(rec) := fcb(rec) - cp (hl) - jp c,endmerge - ;fcb extent number >= dir extent number - ld (hl),a ;buff(ext) = fcb(ext) - ;update directory record count field - ld bc,reccnt-extnum - add hl,bc - ex de,hl - add hl,bc - ;DE=.buff(reccnt), HL=.fcb(reccnt) - ld a,(hl) - ld (de),a ;buff(reccnt)=fcb(reccnt) -endmerge: - ld a,true - ld (fcb$copied),a ;mark as copied - jp seek$copy ;ok to "wrdir" here - 1.4 compat - ; ret - -mergerr: ;elements did not merge correctly - ld hl,lret - dec (hl) ;=255 non zero flag set - ret - -make: ;create a new file by creating a directory entry - ;then opening the file - call check$write ;may be write protected - ld hl,(info) - push hl ;save fcb address, look for e5 - ld hl,efcb - ld (info),hl ;info = .empty - ld c,1 - call search ;length 1 match on empty entry - call end$of$dir ;zero flag set if no space - pop hl ;recall info address - ld (info),hl ;in case we return here - ret z ;return with error condition 255 if not found - ex de,hl ;DE = info address - ;clear the remainder of the fcb - ld hl,namlen - add hl,de ;HL=.fcb(namlen) - ld c,fcblen-namlen ;number of bytes to fill - xor a ;clear accumulator to 00 for fill -make0: ld (hl),a - inc hl - dec c - jp nz,make0 - ld hl,ubytes - add hl,de ;HL = .fcb(ubytes) - ld (hl),a ;fcb(ubytes) = 0 - call setcdr ;may have extended the directory - ;now copy entry to the directory - call copy$fcb - ;and set the file write flag to "1" - jp setfwf -; ret - -open$reel: ;close the current extent, and open the next one - ;if possible. RMF is true if in read mode - xor a - ld (fcb$copied),a ;set true if actually copied - call close ;close current extent - ;lret remains at enddir if we cannot open the next ext - call end$of$dir - ret z ;return if end - ;increment extent number - ld hl,(info) - ld bc,extnum - add hl,bc ;HL=.fcb(extnum) - ld a,(hl) - inc a - and maxext - ld (hl),a ;fcb(extnum)=++1 - jp z,open$mod ;move to next module if zero - ;may be in the same extent group - ld b,a - ld a,(extmsk) - and b - ;if result is zero, then not in the same group - ld hl,fcb$copied ;true if the fcb was copied to directory - and (hl) ;produces a 00 in accumulator if not written - jp z,open$reel0 ;go to next physical extent - ;result is non zero, so we must be in same logical ext - jp open$reel1 ;to copy fcb information -open$mod: ;extent number overflow, go to next module - ld bc,modnum-extnum - add hl,bc ;HL=.fcb(modnum) - inc (hl) ;fcb(modnum)=++1 - ;module number incremented, check for overflow - ld a,(hl) - and maxmod ;mask high order bits - jp z,open$r$err ;cannot overflow to zero - ;otherwise, ok to continue with new module -open$reel0: - ld c,namlen - call search ;next extent found? - call end$of$dir - jp nz,open$reel1 - ;end of file encountered - ld a,(rmf) - inc a ;0ffh becomes 00 if read - jp z,open$r$err ;sets lret = 1 - ;try to extend the current file - call make - ;cannot be end of directory - call end$of$dir - jp z,open$r$err ;with lret = 1 - jp open$reel2 - -open$reel1: ;not end of file, open - call open$copy -open$reel2: - call getfcb ;set parameters - xor a - jp sta$ret ;lret = 0 -; ret ;with lret = 0 - -open$r$err: ;cannot move to next extent of this file - call setlret1 ;lret = 1 - jp setfwf ;ensure that it will not be closed -; ret - -seqdiskread: ;sequential disk read operation - ld a,1 - ld (seqio),a - ;drop through to diskread - -diskread: ;(may enter from seqdiskread) - ld a,true - ld (rmf),a ;read mode flag = true (open$reel) - ;read the next record from the current fcb - call getfcb ;sets parameters for the read - ld a,(vrecord) - ld hl,rcount - cp (hl) ;vrecord-rcount - ;skip if rcount > vrecord - jp c,recordok - ;not enough records in the extent - ;record count must be 128 to continue - cp 128 ;vrecord = 128? - jp nz,diskeof ;skip if vrecord<>128 - call open$reel ;go to next extent if so - xor a - ld (vrecord),a ;vrecord=00 - ;now check for open ok - ld a,(lret) - or a - jp nz,diskeof ;stop at eof -recordok: ;arrive with fcb addressing a record to read - call index - ;error 2 if reading unwritten data - ;(returns 1 to be compatible with 1.4) - call allocated ;arecord=0000? - jp z,diskeof - ;record has been allocated, read it - call atran ;arecord now a disk address - call seek ;to proper track,sector - call rdbuff ;to dma address - jp setfcb ;replace parameter -; ret - -diskeof: - jp setlret1 ;lret = 1 -; ret - -seqdiskwrite: ;sequential disk write - ld a,1 - ld (seqio),a - ;drop through to diskwrite - -diskwrite: ;(may enter here from seqdiskwrite above) - ld a,false - ld (rmf),a ;read mode flag - ;write record to currently selected file - call check$write ;in case write protected - ld hl,(info) ;HL = .fcb(0) - call check$rofile ;may be a read-only file - call getfcb ;to set local parameters - ld a,(vrecord) - cp lstrec+1 ;vrecord-128 - ;skip if vrecord > lstrec - ;vrecord = 128, cannot open next extent - jp nc,setlret1 ;lret=1 -diskwr0: ;can write the next record, so continue - call index - call allocated - ld c,0 ;marked as normal write operation for wrbuff - jp nz,diskwr1 - ;not allocated - ;the argument to getblock is the starting - ;position for the disk search, and should be - ;the last allocated block for this file, or - ;the value 0 if no space has been allocated - call dm$position - ld (dminx),a ;save for later - ld bc,0000h ;may use block zero - or a - jp z,nopblock ;skip if no previous block - ;previous block exists at A - ld c,a - dec bc ;previous block # in BC - call getdm ;previous block # to HL - ld b,h - ld c,l ;BC=prev block# -nopblock: ;BC = 0000, or previous block # - call get$block ;block # to HL - ;arrive here with block# or zero - ld a,l - or h - jp nz,blockok - ;cannot find a block to allocate - ld a,2 - jp sta$ret ;lret=2 - -blockok: ;allocated block number is in HL - ld (arecord),hl - ex de,hl ;block number to DE - ld hl,(info) - ld bc,dskmap - add hl,bc ;HL=.fcb(dskmap) - ld a,(single) - or a ;set flags for single byte dm - ld a,(dminx) ;recall dm index - jp z,allocwd ;skip if allocating word - ;allocating a byte value - call addh - ld (hl),e ;single byte alloc - jp diskwru ;to continue - -allocwd: ;allocate a word value - ld c,a - ld b,0 ;double(dminx) - add hl,bc - add hl,bc ;HL=.fcb(dminx*2) - ld (hl),e - inc hl - ld (hl),d ;double wd -diskwru: ;disk write to previously unallocated block - ld c,2 ;marked as unallocated write -diskwr1: ;continue the write operation of no allocation error - ;C = 0 if normal write, 2 if to prev unalloc block - ld a,(lret) - or a - ret nz ;stop if non zero returned value - push bc ;save write flag - call atran ;arecord set - ld a,(seqio) - dec a - dec a - jp nz,diskwr11 - pop bc - push bc - ld a,c - dec a - dec a - jp nz,diskwr11 ;old allocation - push hl ;arecord in hl ret from atran - ld hl,(buffa) - ld d,a ;zero buffa & fill -fill0: ld (hl),a - inc hl - inc d - jp p,fill0 - call setdir - ld hl,(arecord1) - ld c,2 -fill1: ld (arecord),hl - push bc - call seek - pop bc - call wrbuff ;write fill record - ld hl,(arecord) ;restore last record - ld c,0 ;change allocate flag - ld a,(blkmsk) - ld b,a - and l - cp b - inc hl - jp nz,fill1 ;cont until cluster is zeroed - pop hl - ld (arecord),hl - call setdata -diskwr11: - call seek ;to proper file position - pop bc - push bc ;restore/save write flag (C=2 if new block) - call wrbuff ;written to disk - pop bc ;C = 2 if a new block was allocated, 0 if not - ;increment record count if rcount<=vrecord - ld a,(vrecord) - ld hl,rcount - cp (hl) ;vrecord-rcount - jp c,diskwr2 - ;rcount <= vrecord - ld (hl),a - inc (hl) ;rcount = vrecord+1 - ld c,2 ;mark as record count incremented -diskwr2: ;A has vrecord, C=2 if new block or new record# - dec c - dec c - jp nz,noupdate - push af ;save vrecord value - call getmodnum ;HL=.fcb(modnum), A=fcb(modnum) - ;reset the file write flag to mark as written fcb - and (not fwfmsk) and 0ffh;bit reset - ld (hl),a ;fcb(modnum) = fcb(modnum) and 7fh - pop af ;restore vrecord -noupdate: ;check for end of extent, if found attempt to open - ;next extent in preparation for next write - cp lstrec ;vrecord=lstrec? - jp nz,diskwr3 ;skip if not - ;may be random access write, if so we are done - ;change next - ld a,(seqio) - cp 1 - jp nz,diskwr3 ;skip next extent open op - ;update current fcb before going to next extent - call setfcb - call open$reel ;rmf=false - ;vrecord remains at lstrec causing eof if - ;no more directory space is available - ld hl,lret - ld a,(hl) - or a - jp nz,nospace - ;space available, set vrecord=255 - dec a - ld (vrecord),a ;goes to 00 next time -nospace: - ld (hl),0 ;lret = 00 for returned value -diskwr3: - jp setfcb ;replace parameters -; ret - -rseek: ;random access seek operation, C=0ffh if read mode - ;fcb is assumed to address an active file control block - ;(modnum has been set to 1100$0000b if previous bad seek) - xor a - ld (seqio),a ;marked as random access operation -rseek1: push bc ;save r/w flag - ld hl,(info) - ex de,hl ;DE will hold base of fcb - ld hl,ranrec - add hl,de ;HL=.fcb(ranrec) - ld a,(hl) - and 7fh - push af ;record number - ld a,(hl) - rla ;cy=lsb of extent# - inc hl - ld a,(hl) - rla - and 11111b ;A=ext# - ld c,a ;C holds extent number, record stacked - ld a,(hl) - rra - rra - rra - rra - and 1111b ;mod# - ld b,a ;B holds module#, C holds ext# - pop af ;recall sought record # - ;check to insure that high byte of ran rec = 00 - inc hl - ld l,(hl) ;l=high byte (must be 00) - inc l - dec l - ld l,6 ;zero flag, l=6 - ;produce error 6, seek past physical eod - jp nz,seekerr - ;otherwise, high byte = 0, A = sought record - ld hl,nxtrec - add hl,de ;HL = .fcb(nxtrec) - ld (hl),a ;sought rec# stored away - ;arrive here with B=mod#, C=ext#, DE=.fcb, rec stored - ;the r/w flag is still stacked. compare fcb values - ld hl,extnum - add hl,de - ld a,c ;A=seek ext# - sub (hl) - jp nz,ranclose ;tests for = extents - ;extents match, check mod# - ld hl,modnum - add hl,de - ld a,b ;B=seek mod# - ;could be overflow at eof, producing module# - ;of 90H or 10H, so compare all but fwf - sub (hl) - and 7fh - jp z,seekok ;same? -ranclose: - push bc - push de ;save seek mod#,ext#, .fcb - call close ;current extent closed - pop de - pop bc ;recall parameters and fill - ld l,3 ;cannot close error #3 - ld a,(lret) - inc a - jp z,badseek - ld hl,extnum - add hl,de - ld (hl),c ;fcb(extnum)=ext# - ld hl,modnum - add hl,de - ld (hl),b ;fcb(modnum)=mod# - call open ;is the file present? - ld a,(lret) - inc a - jp nz,seekok ;open successful? - ;cannot open the file, read mode? - pop bc ;r/w flag to c (=0ffh if read) - push bc ;everyone expects this item stacked - ld l,4 ;seek to unwritten extent #4 - inc c ;becomes 00 if read operation - jp z,badseek ;skip to error if read operation - ;write operation, make new extent - call make - ld l,5 ;cannot create new extent #5 - ld a,(lret) - inc a - jp z,badseek ;no dir space - ;file make operation successful -seekok: - pop bc ;discard r/w flag - xor a - jp sta$ret ;with zero set -badseek: ;fcb no longer contains a valid fcb, mark - ;with 1100$000b in modnum field so that it - ;appears as overflow with file write flag set - push hl ;save error flag - call getmodnum ;HL = .modnum - ld (hl),11000000b - pop hl ;and drop through -seekerr: - pop bc ;discard r/w flag - ld a,l - ld (lret),a ;lret=#, nonzero - ;setfwf returns non-zero accumulator for err - jp setfwf ;flag set, so subsequent close ok -; ret - -randiskread: ;random disk read operation - ld c,true ;marked as read operation - call rseek - call z,diskread ;if seek successful - ret - -randiskwrite: ;random disk write operation - ld c,false ;marked as write operation - call rseek - call z,diskwrite ;if seek successful - ret - -compute$rr: ;compute random record position for getfilesize/setrandom - ex de,hl - add hl,de - ;DE=.buf(dptr) or .fcb(0), HL = .f(nxtrec/reccnt) - ld c,(hl) - ld b,0 ;BC = 0000 0000 ?rrr rrrr - ld hl,extnum - add hl,de - ld a,(hl) - rrca - and 80h ;A=e000 0000 - add a,c - ld c,a - ld a,0 - adc a,b - ld b,a - ;BC = 0000 000? errrr rrrr - ld a,(hl) - rrca - and 0fh - add a,b - ld b,a - ;BC = 000? eeee errrr rrrr - ld hl,modnum - add hl,de - ld a,(hl) ;A=XXX? mmmm - add a,a - add a,a - add a,a - add a,a ;cy=? A=mmmm 0000 - push af - add a,b - ld b,a - ;cy=?, BC = mmmm eeee errr rrrr - push af ;possible second carry - pop hl ;cy = lsb of L - ld a,l ;cy = lsb of A - pop hl ;cy = lsb of L - or l ;cy/cy = lsb of A - and 1 ;A = 0000 000? possible carry-out - ret - -getfilesize: ;compute logical file size for current fcb - ld c,extnum - call search - ;zero the receiving ranrec field - ld hl,(info) - ld de,ranrec - add hl,de - push hl ;save position - ld (hl),d - inc hl - ld (hl),d - inc hl - ld (hl),d ;=00 00 00 -getsize: - call end$of$dir - jp z,setsize - ;current fcb addressed by dptr - call getdptra - ld de,reccnt ;ready for compute size - call compute$rr - ;A=0000 000? BC = mmmm eeee errr rrrr - ;compare with memory, larger? - pop hl - push hl ;recall, replace .fcb(ranrec) - ld e,a ;save cy - ld a,c - sub (hl) - inc hl ;ls byte - ld a,b - sbc a,(hl) - inc hl ;middle byte - ld a,e - sbc a,(hl) ;carry if .fcb(ranrec) > directory - jp c,getnextsize ;for another try - ;fcb is less or equal, fill from directory - ld (hl),e - dec hl - ld (hl),b - dec hl - ld (hl),c -getnextsize: - call searchn - jp getsize - -setsize: - pop hl ;discard .fcb(ranrec) - ret - -setrandom: ;set random record from the current file control block - ld hl,(info) - ld de,nxtrec ;ready params for computesize - call compute$rr ;DE=info, A=cy, BC=mmmm eeee errr rrrr - ld hl,ranrec - add hl,de ;HL = .fcb(ranrec) - ld (hl),c - inc hl - ld (hl),b - inc hl - ld (hl),a ;to ranrec - ret - -select: ;select disk info for subsequent input or output ops - ld hl,(dlog) - ld a,(curdsk) - ld c,a - call hlrotr - push hl - ex de,hl ;save it for test below, send to seldsk - call selectdisk - pop hl ;recall dlog vector - call z,sel$error ;returns true if select ok - ;is the disk logged in? - ld a,l - rra - ret c ;return if bit is set - ;disk not logged in, set bit and initialize - ld hl,(dlog) - ld c,l - ld b,h ;call ready - call set$cdisk - ld (dlog),hl ;dlog=set$cdisk(dlog) - jp initialize -; ret - -curselect: - ld a,(linfo) - ld hl,curdsk - cp (hl) - ret z ;skip if linfo=curdsk - ld (hl),a ;curdsk=info - jp select -; ret - -reselect: ;check current fcb to see if reselection necessary - ld a,true - ld (resel),a ;mark possible reselect - ld hl,(info) - ld a,(hl) ;drive select code - and 11111b ;non zero is auto drive select - dec a ;drive code normalized to 0..30, or 255 - ld (linfo),a ;save drive code - cp 30 - jp nc,noselect - ;auto select function, save curdsk - ld a,(curdsk) - ld (olddsk),a ;olddsk=curdsk - ld a,(hl) - ld (fcbdsk),a ;save drive code - -;; and 11100000b - and 0b11100000 - - ld (hl),a ;preserve hi bits - call curselect -noselect: ;set user code - ld a,(usrcode) ;0...31 - ld hl,(info) - or (hl) - ld (hl),a - ret - -; individual function handlers -func12: ;return version number - ld a,dvers - jp sta$ret ;lret = dvers (high = 00) -; ret -; jp goback - -func13: ;reset disk system - initialize to disk 0 - ld hl,0 - ld (rodsk),hl - ld (dlog),hl - xor a - ld (curdsk),a ;note that usrcode remains unchanged - ld hl,tbuff - ld (dmaad),hl ;dmaad = tbuff - call setdata ;to data dma address - jp select -; ret -; jp goback - -func14 equ curselect ;select disk info -; ret -; jp goback - -func15: ;open file - call clrmodnum ;clear the module number - call reselect - jp open -; ret -; jp goback - -func16: ;close file - call reselect - jp close -; ret -; jp goback - -func17: ;search for first occurrence of a file - ld c,0 ;length assuming '?' true - ex de,hl ;was lhld info - ld a,(hl) - cp '?' ;no reselect if ? - jp z,qselect ;skip reselect if so - ;normal search - call getexta - ld a,(hl) - cp '?' ; - call nz,clrmodnum ;module number zeroed - call reselect - ld c,namlen -qselect: - call search - jp dir$to$user ;copy directory entry to user -; ret -; jp goback - -func18: ;search for next occurrence of a file name - ld hl,(searcha) - ld (info),hl - call reselect - call searchn - jp dir$to$user ;copy directory entry to user -; ret -; jp goback - -func19: ;delete a file - call reselect - call delete - jp copy$dirloc -; ret -; jp goback - -func20: ;read a file - call reselect - jp seqdiskread -; jp goback - -func21: ;write a file - call reselect - jp seqdiskwrite -; jp goback - -func22: ;make a file - call clrmodnum - call reselect - jp make -; ret -; jp goback - -func23: ;rename a file - call reselect - call rename - jp copy$dirloc -; ret -; jp goback - -func24: ;return the login vector - ld hl,(dlog) - jp sthl$ret -; ret -; jp goback - -func25: ;return selected disk number - ld a,(curdsk) - jp sta$ret -; ret -; jp goback - -func26: ;set the subsequent dma address to info - ex de,hl ;was lhld info - ld (dmaad),hl ;dmaad = info - jp setdata ;to data dma address -; ret -; jp goback - -func27: ;return the login vector address - ld hl,(alloca) - jp sthl$ret -; ret -; jp goback - -func28 equ set$ro - ;write protect current disk -; ret -; jp goback - -func29: ;return r/o bit vector - ld hl,(rodsk) - jp sthl$ret -; ret -; jp goback - -func30: ;set file indicators - call reselect - call indicators - jp copy$dirloc ;lret=dirloc -; ret -; jp goback - -func31: ;return address of disk parameter block - ld hl,(dpbaddr) -sthl$ret: - ld (aret),hl - ret -; jp goback - -func32: ;set user code - ld a,(linfo) - cp 0ffh - jp nz,setusrcode - ;interrogate user code instead - ld a,(usrcode) - jp sta$ret ;lret=usrcode -; ret -; jp goback - -setusrcode: - and 1fh - ld (usrcode),a - ret -; jp goback - -func33: ;random disk read operation - call reselect - jp randiskread ;to perform the disk read -; ret -; jp goback - -func34: ;random disk write operation - call reselect - jp randiskwrite ;to perform the disk write -; ret -; jp goback - -func35: ;return file size (0-65536) - call reselect - jp getfilesize -; ret -; jp goback - -func36 equ setrandom ;set random record -; ret -; jp goback - -func37: ld hl,(info) - ld a,l - cpl - ld e,a - ld a,h - cpl - ld hl,(dlog) - and h - ld d,a - ld a,l - and e - ld e,a - ld hl,(rodsk) - ex de,hl - ld (dlog),hl - ld a,l - and e - ld l,a - ld a,h - and d - ld h,a - ld (rodsk),hl - ret - -goback: ;arrive here at end of processing to return to user - ld a,(resel) - or a - jp z,retmon - ;reselection may have taken place - ld hl,(info) - ld (hl),0 ;fcb(0)=0 - ld a,(fcbdsk) - or a - jp z,retmon - ;restore disk number - ld (hl),a ;fcb(0)=fcbdsk - ld a,(olddsk) - ld (linfo),a - call curselect - -; return from the disk monitor -retmon: ld hl,(entsp) - ld sp,hl ;user stack restored - ld hl,(aret) - ld a,l - ld b,h ;BA = HL = aret - ret - -func38 equ func$ret -func39 equ func$ret -func40: ;random disk write with zero fill of unallocated block - call reselect - ld a,2 - ld (seqio),a - ld c,false - call rseek1 - call z,diskwrite ;if seek successful - ret - -; data areas - -; initialized data -efcb: .db empty ;0e5=available dir entry -rodsk: .dw 0 ;read only disk vector -dlog: .dw 0 ;logged-in disks -dmaad: .dw tbuff ;initial dma address - -; curtrka - alloca are set upon disk select -; (data must be adjacent, do not insert variables) -; (address of translate vector, not used) -cdrmaxa: - .ds word ;pointer to cur dir max value -curtrka: - .ds word ;current track address -curreca: - .ds word ;current record address -buffa: .ds word ;pointer to directory dma address -dpbaddr: - .ds word ;current disk parameter block address -checka: .ds word ;current checksum vector address -alloca: .ds word ;current allocation vector address - -addlist equ $-buffa ;address list size - -; sectpt - offset obtained from disk parm block at dpbaddr -; (data must be adjacent, do not insert variables) -sectpt: .ds word ;sectors per track -blkshf: .ds byte ;block shift factor -blkmsk: .ds byte ;block mask -extmsk: .ds byte ;extent mask -maxall: .ds word ;maximum allocation number -dirmax: .ds word ;largest directory number -dirblk: .ds word ;reserved allocation bits for directory -chksiz: .ds word ;size of checksum vector -offset: .ds word ;offset tracks at beginning - -dpblist equ $-sectpt ;size of area - -; local variables -tranv: ds word ;address of translate vector -fcb$copied: - ds byte ;set true if copy$fcb called -rmf: ds byte ;read mode flag for open$reel -dirloc: ds byte ;directory flag in rename, etc. -seqio: ds byte ;1 if sequential i/o -linfo: ds byte ;low(info) -dminx: ds byte ;local for diskwrite -searchl: - ds byte ;search length -searcha: - ds word ;search address -tinfo: ds word ;temp for info in "make" -single: ds byte ;set true if single byte allocation map -resel: ds byte ;reselection flag -olddsk: ds byte ;disk on entry to bdos -fcbdsk: ds byte ;disk named in fcb -rcount: ds byte ;record count in current fcb -extval: ds byte ;extent number and extmsk -vrecord: - ds word ;current virtual record -arecord: - ds word ;current actual record -arecord1: - ds word ;current actual block# * blkmsk - -; local variables for directory access -dptr: ds byte ;directory pointer 0,1,2,3 -dcnt: ds word ;directory counter 0,1,...,dirmax -drec: ds word ;directory record 0,1,...,dirmax/4 - -;bios equ ($ and 0ff00h)+100h;next module - - end - - - - - - ;; Ordering of segments for the linker. - .area _HOME - .area _CODE - .area _GSINIT - .area _GSFINAL - - .area _DATA - .area _BSEG - .area _BSS - .area _HEAP - - .area _CODE -.if 0 -__clock:: - ld a,#2 - rst 0x08 - ret -.endif - -_exit:: - ;; Exit - special code to the emulator - ld a,#0 - rst 0x08 -1$: - halt - jr 1$ - - .area _GSINIT -gsinit:: - - .area _GSFINAL - ret diff --git a/doug/src/cpmbdos.lst b/doug/src/cpmbdos.lst deleted file mode 100755 index 659ab2c8..00000000 --- a/doug/src/cpmbdos.lst +++ /dev/null @@ -1,65 +0,0 @@ - 1 ;-------------------------------------------------------- - 2 ; File Created by SDCC : free open source ANSI-C Compiler - 3 ; Version 3.0.2 #6489 (May 10 2011) (Mac OS X x86_64) - 4 ; This file was generated Wed May 11 05:28:20 2011 - 5 ;-------------------------------------------------------- - 6 .module cpmbdos - 7 .optsdcc -mz80 - 8 - 9 ;-------------------------------------------------------- - 10 ; Public variables in this module - 11 ;-------------------------------------------------------- - 12 .globl _cpmbdos - 13 ;-------------------------------------------------------- - 14 ; special function registers - 15 ;-------------------------------------------------------- - 16 ;-------------------------------------------------------- - 17 ; ram data - 18 ;-------------------------------------------------------- - 19 .area _DATA - 20 ;-------------------------------------------------------- - 21 ; overlayable items in ram - 22 ;-------------------------------------------------------- - 23 .area _OVERLAY - 24 ;-------------------------------------------------------- - 25 ; external initialized ram data - 26 ;-------------------------------------------------------- - 27 ;-------------------------------------------------------- - 28 ; global & static initialisations - 29 ;-------------------------------------------------------- - 30 .area _HOME - 31 .area _GSINIT - 32 .area _GSFINAL - 33 .area _GSINIT - 34 ;-------------------------------------------------------- - 35 ; Home - 36 ;-------------------------------------------------------- - 37 .area _HOME - 38 .area _HOME - 39 ;-------------------------------------------------------- - 40 ; code - 41 ;-------------------------------------------------------- - 42 .area _CODE - 43 ;cpmbdos.c:1: unsigned char cpmbdos(void * p) - 44 ; --------------------------------- - 45 ; Function cpmbdos - 46 ; --------------------------------- - 0000 47 _cpmbdos_start:: - 0000 48 _cpmbdos: - 0000 DD E5 49 push ix - 0002 DD 21 00 00 50 ld ix,#0 - 0006 DD 39 51 add ix,sp - 52 ;cpmbdos.c:3: return 2; - 0008 DD 6E 04 53 ld l,4(ix) - 000B DD 66 05 54 ld h,5(ix) - 000E 4E 55 ld c,(hl) - 000F 23 56 inc hl - 0010 5E 57 ld e,(hl) - 0011 23 58 inc hl - 0012 56 59 ld d,(hl) - 0013 CD 05 00 60 call 5 - 0016 DD E1 61 pop ix - 0018 C9 62 ret - 0019 63 _cpmbdos_end:: - 64 .area _CODE - 65 .area _CABS diff --git a/doug/src/cpmbdos.rel b/doug/src/cpmbdos.rel deleted file mode 100755 index c7464cec..00000000 --- a/doug/src/cpmbdos.rel +++ /dev/null @@ -1,25 +0,0 @@ -XL -H 7 areas 4 global symbols -M cpmbdos -O -mz80 -S .__.ABS. Def0000 -A _CODE size 19 flags 0 addr 0 -S _cpmbdos Def0000 -S _cpmbdos_start Def0000 -S _cpmbdos_end Def0019 -A _DATA size 0 flags 0 addr 0 -A _OVERLAY size 0 flags 0 addr 0 -A _HOME size 0 flags 0 addr 0 -A _GSINIT size 0 flags 0 addr 0 -A _GSFINAL size 0 flags 0 addr 0 -A _CABS size 0 flags 0 addr 0 -T 00 00 -R 00 00 00 00 -T 00 00 -R 00 00 00 00 -T 00 00 DD E5 DD 21 00 00 DD 39 DD 6E 04 DD 66 05 -R 00 00 00 00 -T 0E 00 4E 23 5E 23 56 CD 05 00 DD E1 C9 -R 00 00 00 00 -T 19 00 -R 00 00 00 00 diff --git a/doug/src/cpmbdos.s b/doug/src/cpmbdos.s deleted file mode 100755 index 01c438e0..00000000 --- a/doug/src/cpmbdos.s +++ /dev/null @@ -1,65 +0,0 @@ -;-------------------------------------------------------- -; File Created by SDCC : free open source ANSI-C Compiler -; Version 3.0.2 #6489 (May 10 2011) (Mac OS X x86_64) -; This file was generated Wed May 11 05:28:20 2011 -;-------------------------------------------------------- - .module cpmbdos - .optsdcc -mz80 - -;-------------------------------------------------------- -; Public variables in this module -;-------------------------------------------------------- - .globl _cpmbdos -;-------------------------------------------------------- -; special function registers -;-------------------------------------------------------- -;-------------------------------------------------------- -; ram data -;-------------------------------------------------------- - .area _DATA -;-------------------------------------------------------- -; overlayable items in ram -;-------------------------------------------------------- - .area _OVERLAY -;-------------------------------------------------------- -; external initialized ram data -;-------------------------------------------------------- -;-------------------------------------------------------- -; global & static initialisations -;-------------------------------------------------------- - .area _HOME - .area _GSINIT - .area _GSFINAL - .area _GSINIT -;-------------------------------------------------------- -; Home -;-------------------------------------------------------- - .area _HOME - .area _HOME -;-------------------------------------------------------- -; code -;-------------------------------------------------------- - .area _CODE -;cpmbdos.c:1: unsigned char cpmbdos(void * p) -; --------------------------------- -; Function cpmbdos -; --------------------------------- -_cpmbdos_start:: -_cpmbdos: - push ix - ld ix,#0 - add ix,sp -;cpmbdos.c:3: return 2; - ld l,4(ix) - ld h,5(ix) - ld c,(hl) - inc hl - ld e,(hl) - inc hl - ld d,(hl) - call 5 - pop ix - ret -_cpmbdos_end:: - .area _CODE - .area _CABS diff --git a/doug/src/cpmbdos.sym b/doug/src/cpmbdos.sym deleted file mode 100755 index e18058e6..00000000 --- a/doug/src/cpmbdos.sym +++ /dev/null @@ -1,17 +0,0 @@ - ASxxxx Assembler V02.00 + NoICE + SDCC mods + Flat24 (Zilog Z80 / Hitachi HD64180), page 1. - -Symbol Table - - .__.ABS.= 0000 G | 0 _cpmbdos 0000 GR | 0 _cpmbdos 0019 GR - 0 _cpmbdos 0000 GR - ASxxxx Assembler V02.00 + NoICE + SDCC mods + Flat24 (Zilog Z80 / Hitachi HD64180), page 2. - -Area Table - - 0 _CODE size 19 flags 0 - 1 _DATA size 0 flags 0 - 2 _OVERLAY size 0 flags 0 - 3 _HOME size 0 flags 0 - 4 _GSINIT size 0 flags 0 - 5 _GSFINAL size 0 flags 0 - 6 _CABS size 0 flags 0 diff --git a/doug/src/cprintf.c b/doug/src/cprintf.c deleted file mode 100755 index 7f94e9bb..00000000 --- a/doug/src/cprintf.c +++ /dev/null @@ -1,267 +0,0 @@ -/* Copyright (C) 1996 Robert de Bath - * This file is part of the Linux-8086 C library and is distributed - * under the GNU Library General Public License. - */ - -/* Modified 14-Jan-2002 by John Coffman for inclusion - * in the set of LILO diagnostics. This code is the property of Robert - * de Bath, and is used with his permission. - */ - -/* Modified 14-Sep-2010 by John Coffman for use with - * the N8VEM SBC-188 BIOS project. - */ -#include -#include - -#undef printf -#define ASM_CVT 0 -#ifndef strlen -int strlen(char *s); -#endif - -void outchar(char ch); -#define putch(ch) outchar((char)ch) - - -#ifndef NULL -# define NULL ((void*)0L) -#endif - -#define __fastcall -#define NUMLTH 11 -static unsigned char * __fastcall __numout(long i, int base, unsigned char out[]); - -int cprintf(const char * fmt, ...) -{ - register int c; - int count = 0; - int type, base; - long val; - char * cp; - char padch=' '; - int minsize, maxsize; - unsigned char out[NUMLTH+1]; - va_list ap; - - va_start(ap, fmt); - - while(c=*fmt++) - { - count++; - if(c!='%') - { - if (c=='\n') putch('\r'); - putch(c); - } - else - { - type=1; - padch = *fmt; - maxsize=minsize=0; - if(padch == '-') fmt++; - - for(;;) - { - c=*fmt++; - if( c<'0' || c>'9' ) break; - minsize*=10; minsize+=c-'0'; - } - - if( c == '.' ) - for(;;) - { - c=*fmt++; - if( c<'0' || c>'9' ) break; - maxsize*=10; maxsize+=c-'0'; - } - - if( padch == '-' ) minsize = -minsize; - else - if( padch != '0' ) padch=' '; - - if( c == 0 ) break; - if(c=='h') - { - c=*fmt++; - type = 0; - } - else if(c=='l') - { - c=*fmt++; - type = 2; - } - - switch(c) - { - case 'X': - case 'x': base=16; type |= 4; if(0) { - case 'o': base= 8; type |= 4; } if(0) { - case 'u': base=10; type |= 4; } if(0) { - case 'd': base=-10; } - switch(type) - { - case 0: val=va_arg(ap, short); break; - case 1: val=va_arg(ap, int); break; - case 2: val=va_arg(ap, long); break; - case 4: val=va_arg(ap, unsigned short); break; - case 5: val=va_arg(ap, unsigned int); break; - case 6: val=va_arg(ap, unsigned long); break; - default:val=0; break; - } - cp = __numout(val,base,out); - if(0) { - case 's': - cp=va_arg(ap, char *); - } - count--; - c = strlen(cp); - if( !maxsize ) maxsize = c; - if( minsize > 0 ) - { - minsize -= c; - while(minsize>0) { putch(padch); count++; minsize--; } - minsize=0; - } - if( minsize < 0 ) minsize= -minsize-c; - while(*cp && maxsize-->0 ) - { - putch(*cp++); - count++; - } - while(minsize>0) { putch(' '); count++; minsize--; } - break; - case 'c': - putch(va_arg(ap, int)); - break; - default: - putch(c); - break; - } - } - } - va_end(ap); - return count; -} - -const char nstring[]="0123456789ABCDEF"; - -#if ASM_CVT==0 - -static unsigned char * -__fastcall -__numout(long i, int base, unsigned char *out) -{ - int n; - int flg = 0; - unsigned long val; - - if (base<0) - { - base = -base; - if (i<0) - { - flg = 1; - i = -i; - } - } - val = i; - - out[NUMLTH] = '\0'; - n = NUMLTH-1; - do - { -#if 1 - out[n] = nstring[val % base]; - val /= base; - --n; -#else - out[n--] = nstring[remLS(val,base)]; - val = divLS(val,base); -#endif - } - while(val); - if(flg) out[n--] = '-'; - - return &out[n+1]; -} -#else - -#asm -! numout.s -! -#if 0 -.data -_nstring: -.ascii "0123456789ABCDEF" -.byte 0 -#endif - -.bss -___out lcomm $C - -.text -___numout: -push bp -mov bp,sp -push di -push si -add sp,*-4 -mov byte ptr -8[bp],*$0 ! flg = 0 -mov si,4[bp] ; i or val.lo -mov di,6[bp] ; i or val.hi -mov cx,8[bp] ; base -test cx,cx ! base < 0 ? -jge .3num -neg cx ! base = -base -or di,di ! i < 0 ? -jns .5num -mov byte ptr -8[bp],*1 ! flg = 1 -neg di ! i = -i -neg si -sbb di,*0 -.5num: -.3num: -mov byte ptr [___out+$B],*$0 ! out[11] = nul -mov -6[bp],*$A ! n = 10 - -.9num: -!!! out[n--] = nstring[val % base]; -xor dx,dx -xchg ax,di -div cx -xchg ax,di -xchg ax,si -div cx -xchg ax,si ! val(new) = val / base - -mov bx,dx ! dx = val % base - -mov al,_nstring[bx] -mov bx,-6[bp] -dec word ptr -6[bp] -mov ___out[bx],al - -mov ax,si -or ax,di ! while (val) -jne .9num - -cmp byte ptr -8[bp],*$0 ! flg == 0 ? -je .Dnum - -mov bx,-6[bp] -dec word ptr -6[bp] -mov byte ptr ___out[bx],*$2D ! out[n--] = minus - -.Dnum: -mov ax,-6[bp] -add ax,#___out+1 - -add sp,*4 -pop si -pop di -pop bp -ret -#endasm - -#endif diff --git a/doug/src/crt0.lst b/doug/src/crt0.lst deleted file mode 100755 index 600c32c1..00000000 --- a/doug/src/crt0.lst +++ /dev/null @@ -1,97 +0,0 @@ - 1 ; modified 4/22/2011 for the N8VEM Home Computer Z180 -- John Coffman - 2 ; - 3 ;-------------------------------------------------------------------------- - 4 ; crt0.s - Generic crt0.s for a Z80 - 5 ; - 6 ; Copyright (C) 2000, Michael Hope - 7 ; - 8 ; This library is free software; you can redistribute it and/or modify it - 9 ; under the terms of the GNU General Public License as published by the - 10 ; Free Software Foundation; either version 2.1, or (at your option) any - 11 ; later version. - 12 ; - 13 ; This library is distributed in the hope that it will be useful, - 14 ; but WITHOUT ANY WARRANTY; without even the implied warranty of - 15 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - 16 ; GNU General Public License for more details. - 17 ; - 18 ; You should have received a copy of the GNU General Public License - 19 ; along with this library; see the file COPYING. If not, write to the - 20 ; Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, - 21 ; MA 02110-1301, USA. - 22 ; - 23 ; As a special exception, if you link this library with other files, - 24 ; some of which are compiled with SDCC, to produce an executable, - 25 ; this library does not by itself cause the resulting executable to - 26 ; be covered by the GNU General Public License. This exception does - 27 ; not however invalidate any other reasons why the executable file - 28 ; might be covered by the GNU General Public License. - 29 ;-------------------------------------------------------------------------- - 30 - 31 ;;; .module crt0 - 32 .globl _main - 33 - 34 .area _HEADER (ABS) - 35 ;; Reset vector - 0000 36 .org 0 - 0000 C3r00s01 37 jp init - 38 - 0008 39 .org 0x08 - 0008 C9 40 ret - 0010 41 .org 0x10 - 0010 C9 42 ret - 0018 43 .org 0x18 - 0018 C9 44 ret - 0020 45 .org 0x20 - 0020 C9 46 ret - 0028 47 .org 0x28 - 0028 C9 48 ret - 0030 49 .org 0x30 - 0030 C9 50 ret - 0038 51 .org 0x38 - 0038 C9 52 ret - 0066 53 .org 0x66 ; NMI interrupt - 0066 ED 45 54 retn - 55 - 0100 56 .org 0x100 - 0100 57 init: - 58 ;; Stack at the top of memory. - 0100 31 FF FF 59 ld sp,#0xffff - 60 - 61 ;; Initialise global variables - 0103 CDr00s00 62 call gsinit - 0106 CDr00s00 63 call _main - 0109 C3r00s00 64 jp _exit - 65 - 66 ;; Ordering of segments for the linker. - 67 .area _HOME - 68 .area _CODE - 69 .area _GSINIT - 70 .area _GSFINAL - 71 - 72 .area _DATA - 73 .area _BSEG - 74 .area _BSS - 75 .area _HEAP - 76 - 77 .area _CODE - 0000 78 .if 0 - 79 __clock:: - 80 ld a,#2 - 81 rst 0x08 - 82 ret - 83 .endif - 84 - 0000 85 _exit:: - 86 ;; Exit - special code to the emulator - 0000 3E 00 87 ld a,#0 - 0002 CF 88 rst 0x08 - 0003 89 1$: - 0003 76 90 halt - 0004 18 FD 91 jr 1$ - 92 - 93 .area _GSINIT - 0000 94 gsinit:: - 95 - 96 .area _GSFINAL - 0000 C9 97 ret diff --git a/doug/src/crt0.rel b/doug/src/crt0.rel deleted file mode 100755 index 2f28cda8..00000000 --- a/doug/src/crt0.rel +++ /dev/null @@ -1,79 +0,0 @@ -XL -H 13 areas 4 global symbols -S _main Ref0000 -S .__.ABS. Def0000 -A _CODE size 6 flags 0 addr 0 -S _exit Def0000 -A _HEADER size 0 flags 8 addr 0 -A _HEADER0 size 3 flags 8 addr 0 -A _HEADER1 size 1 flags 8 addr 8 -A _HEADER2 size 1 flags 8 addr 10 -A _HEADER3 size 1 flags 8 addr 18 -A _HEADER4 size 1 flags 8 addr 20 -A _HEADER5 size 1 flags 8 addr 28 -A _HEADER6 size 1 flags 8 addr 30 -A _HEADER7 size 1 flags 8 addr 38 -A _HEADER8 size 2 flags 8 addr 66 -A _HEADER9 size C flags 8 addr 100 -A _HOME size 0 flags 0 addr 0 -A _GSINIT size 0 flags 0 addr 0 -S gsinit Def0000 -A _GSFINAL size 1 flags 0 addr 0 -A _DATA size 0 flags 0 addr 0 -A _BSEG size 0 flags 0 addr 0 -A _BSS size 0 flags 0 addr 0 -A _HEAP size 0 flags 0 addr 0 -T 00 00 -R 00 00 02 00 -T 00 00 C3 00 01 -R 00 00 02 00 00 03 0B 00 -T 08 00 -R 00 00 03 00 -T 08 00 C9 -R 00 00 03 00 -T 10 00 -R 00 00 04 00 -T 10 00 C9 -R 00 00 04 00 -T 18 00 -R 00 00 05 00 -T 18 00 C9 -R 00 00 05 00 -T 20 00 -R 00 00 06 00 -T 20 00 C9 -R 00 00 06 00 -T 28 00 -R 00 00 07 00 -T 28 00 C9 -R 00 00 07 00 -T 30 00 -R 00 00 08 00 -T 30 00 C9 -R 00 00 08 00 -T 38 00 -R 00 00 09 00 -T 38 00 C9 -R 00 00 09 00 -T 66 00 -R 00 00 0A 00 -T 66 00 ED 45 -R 00 00 0A 00 -T 00 01 -R 00 00 0B 00 -T 00 01 -R 00 00 0B 00 -T 00 01 31 FF FF CD 00 00 CD 00 00 C3 00 00 -R 00 00 0B 00 00 06 0D 00 02 09 00 00 00 0C 00 00 -T 00 00 -R 00 00 00 00 -T 00 00 3E 00 CF -R 00 00 00 00 -T 03 00 -R 00 00 00 00 -T 03 00 76 18 FD -R 00 00 00 00 -T 00 00 -R 00 00 0D 00 -T 00 00 C9 -R 00 00 0E 00 diff --git a/doug/src/crt0.s b/doug/src/crt0.s deleted file mode 100755 index cd5212df..00000000 --- a/doug/src/crt0.s +++ /dev/null @@ -1,97 +0,0 @@ -; modified 4/22/2011 for the N8VEM Home Computer Z180 -- John Coffman -; -;-------------------------------------------------------------------------- -; crt0.s - Generic crt0.s for a Z80 -; -; Copyright (C) 2000, Michael Hope -; -; This library is free software; you can redistribute it and/or modify it -; under the terms of the GNU General Public License as published by the -; Free Software Foundation; either version 2.1, or (at your option) any -; later version. -; -; This library is distributed in the hope that it will be useful, -; but WITHOUT ANY WARRANTY; without even the implied warranty of -; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -; GNU General Public License for more details. -; -; You should have received a copy of the GNU General Public License -; along with this library; see the file COPYING. If not, write to the -; Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, -; MA 02110-1301, USA. -; -; As a special exception, if you link this library with other files, -; some of which are compiled with SDCC, to produce an executable, -; this library does not by itself cause the resulting executable to -; be covered by the GNU General Public License. This exception does -; not however invalidate any other reasons why the executable file -; might be covered by the GNU General Public License. -;-------------------------------------------------------------------------- - -;;; .module crt0 - .globl _main - - .area _HEADER (ABS) - ;; Reset vector - .org 0 - jp init - - .org 0x08 - ret - .org 0x10 - ret - .org 0x18 - ret - .org 0x20 - ret - .org 0x28 - ret - .org 0x30 - ret - .org 0x38 - ret - .org 0x66 ; NMI interrupt - retn - - .org 0x100 -init: - ;; Stack at the top of memory. - ld sp,#0xffff - - ;; Initialise global variables - call gsinit - call _main - jp _exit - - ;; Ordering of segments for the linker. - .area _HOME - .area _CODE - .area _GSINIT - .area _GSFINAL - - .area _DATA - .area _BSEG - .area _BSS - .area _HEAP - - .area _CODE -.if 0 -__clock:: - ld a,#2 - rst 0x08 - ret -.endif - -_exit:: - ;; Exit - special code to the emulator - ld a,#0 - rst 0x08 -1$: - halt - jr 1$ - - .area _GSINIT -gsinit:: - - .area _GSFINAL - ret diff --git a/doug/src/crt0.sym b/doug/src/crt0.sym deleted file mode 100755 index eb73396b..00000000 --- a/doug/src/crt0.sym +++ /dev/null @@ -1,29 +0,0 @@ - ASxxxx Assembler V02.00 + NoICE + SDCC mods + Flat24 (Zilog Z80 / Hitachi HD64180), page 1. - -Symbol Table - - .__.ABS.= 0000 G | 0 _exit 0000 GR | _main **** GX - D gsinit 0000 GR | B init 0100 R - ASxxxx Assembler V02.00 + NoICE + SDCC mods + Flat24 (Zilog Z80 / Hitachi HD64180), page 2. - -Area Table - - 0 _CODE size 6 flags 0 - 1 _HEADER size 0 flags 8 - 2 _HEADER0 size 3 flags 8 - 3 _HEADER1 size 1 flags 8 - 4 _HEADER2 size 1 flags 8 - 5 _HEADER3 size 1 flags 8 - 6 _HEADER4 size 1 flags 8 - 7 _HEADER5 size 1 flags 8 - 8 _HEADER6 size 1 flags 8 - 9 _HEADER7 size 1 flags 8 - A _HEADER8 size 2 flags 8 - B _HEADER9 size C flags 8 - C _HOME size 0 flags 0 - D _GSINIT size 0 flags 0 - E _GSFINAL size 1 flags 0 - F _DATA size 0 flags 0 - 10 _BSEG size 0 flags 0 - 11 _BSS size 0 flags 0 - 12 _HEAP size 0 flags 0 diff --git a/doug/src/crt0jplp.lst b/doug/src/crt0jplp.lst deleted file mode 100644 index b23ba63f..00000000 --- a/doug/src/crt0jplp.lst +++ /dev/null @@ -1,9 +0,0 @@ - 1 ;-------------------------------------------------------------------------- - 2 ; crt0jplp.s 8/7/2011 dwg - - Generic crt0.s for a Z80 with jump loop - 3 ;-------------------------------------------------------------------------- - 4 - 5 .area _HEADER (ABS) - 0000 6 .org 0 - 0000 C3r00s00 7 jploop: jp jploop - 8 - 9 diff --git a/doug/src/crt0jplp.rel b/doug/src/crt0jplp.rel deleted file mode 100644 index 2b867446..00000000 --- a/doug/src/crt0jplp.rel +++ /dev/null @@ -1,10 +0,0 @@ -XL -H 3 areas 1 global symbols -S .__.ABS. Def0000 -A _CODE size 0 flags 0 addr 0 -A _HEADER size 0 flags 8 addr 0 -A _HEADER0 size 3 flags 8 addr 0 -T 00 00 -R 00 00 02 00 -T 00 00 C3 00 00 -R 00 00 02 00 00 03 02 00 diff --git a/doug/src/crt0jplp.s b/doug/src/crt0jplp.s deleted file mode 100755 index 41005105..00000000 --- a/doug/src/crt0jplp.s +++ /dev/null @@ -1,9 +0,0 @@ -;-------------------------------------------------------------------------- -; crt0jplp.s 8/7/2011 dwg - - Generic crt0.s for a Z80 with jump loop -;-------------------------------------------------------------------------- - - .area _HEADER (ABS) - .org 0 -jploop: jp jploop - - diff --git a/doug/src/crt0jplp.sym b/doug/src/crt0jplp.sym deleted file mode 100644 index 2ac002fe..00000000 --- a/doug/src/crt0jplp.sym +++ /dev/null @@ -1,12 +0,0 @@ - ASxxxx Assembler V02.00 + NoICE + SDCC mods + Flat24 (Zilog Z80 / Hitachi HD64180), page 1. - -Symbol Table - - .__.ABS.= 0000 G | 2 jploop 0000 R - ASxxxx Assembler V02.00 + NoICE + SDCC mods + Flat24 (Zilog Z80 / Hitachi HD64180), page 2. - -Area Table - - 0 _CODE size 0 flags 0 - 1 _HEADER size 0 flags 8 - 2 _HEADER0 size 3 flags 8 diff --git a/doug/src/crt0scrm.lst b/doug/src/crt0scrm.lst deleted file mode 100644 index 231c555a..00000000 --- a/doug/src/crt0scrm.lst +++ /dev/null @@ -1,72 +0,0 @@ - 1 ;-------------------------------------------------------------------------- - 2 ; crt0scrm.s 8/7/2011 dwg - - Generic crt0.s for a Z80 with jump loop - 3 ;-------------------------------------------------------------------------- - 4 - 5 - 6 .area _HEADER (ABS) - 0000 7 .org 0 - 8 - 9 .include "scsi2ide.inc" - 1 ; scsi2ide.inc 8/7/2011 dwg - macros describing the N8VEM SCSI2IDE - 2 - 0000 3 SCSI2IDE_IO_BASE = 0 - 4 - 0010 5 UART_IO_BASE = SCSI2IDE_IO_BASE+16 - 6 - 0010 7 rUART_RDR = UART_IO_BASE + 0 - 0010 8 wUART_TDR = UART_IO_BASE + 0 - 0010 9 wUART_DIV_LO = UART_IO_BASE + 0 - 0011 10 wUART_DIV_HI = UART_IO_BASE + 1 - 0011 11 wUART_IER = UART_IO_BASE + 1 - 0012 12 rUART_IIR = UART_IO_BASE + 2 - 0013 13 wUART_LCR = UART_IO_BASE + 3 - 0014 14 wUART_MCR = UART_IO_BASE + 4 - 0015 15 rUART_LSR = UART_IO_BASE + 5 - 0016 16 rUART_MSR = UART_IO_BASE + 6 - 0017 17 wUART_FCR = UART_IO_BASE + 7 - 18 - 19 ; eof - scsi2ide.inc - 20 - 10 .include "ns16550.inc" - 1 ; ns16550.inc 8/7/2011 dwg - National 16550 - 2 - 0080 3 UART_DLAB = 0x80 - 000C 4 UART_BAUD_9600 = 12 - 0001 5 UART_RDA = 0x01 - 0020 6 UART_TBE = 0x20 - 7 - 8 ; eof - ns16550.inc - 11 - 0000 12 scream: - 13 - 0000 3E 80 14 ld a,#UART_DLAB - 0002 D3 13 15 out (wUART_LCR),a - 16 - 0004 3E 00 17 ld a,#0x00 - 0006 D3 11 18 out (wUART_DIV_HI),a - 19 - 0008 3E 0C 20 ld a,#UART_BAUD_9600 - 000A D3 10 21 out (wUART_DIV_LO),a - 22 - 000C 3E 00 23 ld a,#0 - 000E D3 13 24 out (wUART_LCR),a - 25 - 0010 3E 03 26 ld a,#0x03 - 0012 D3 13 27 out (wUART_LCR),a - 28 - 0014 3E 03 29 ld a,#0x03 - 0016 D3 14 30 out (wUART_MCR),a - 31 - 0018 32 scrmlp: - 0018 DB 15 33 in a,(rUART_LSR) - 001A E6 20 34 and a,#UART_TBE - 001C CAr18s00 35 jp z,scrmlp - 36 - 001F 3E 30 37 ld a,#0x30 ; ascii 0 (zero) - 0021 D3 10 38 out (wUART_TDR),a - 39 - 0023 C3r18s00 40 jp scrmlp - 41 - 42 - 43 - 44 diff --git a/doug/src/crt0scrm.rel b/doug/src/crt0scrm.rel deleted file mode 100644 index 76e135ea..00000000 --- a/doug/src/crt0scrm.rel +++ /dev/null @@ -1,18 +0,0 @@ -XL -H 3 areas 1 global symbols -S .__.ABS. Def0000 -A _CODE size 0 flags 0 addr 0 -A _HEADER size 0 flags 8 addr 0 -A _HEADER0 size 26 flags 8 addr 0 -T 00 00 -R 00 00 02 00 -T 00 00 -R 00 00 02 00 -T 00 00 3E 80 D3 13 3E 00 D3 11 3E 0C D3 10 3E 00 -R 00 00 02 00 -T 0E 00 D3 13 3E 03 D3 13 3E 03 D3 14 -R 00 00 02 00 -T 18 00 -R 00 00 02 00 -T 18 00 DB 15 E6 20 CA 18 00 3E 30 D3 10 C3 18 00 -R 00 00 02 00 00 07 02 00 00 0E 02 00 diff --git a/doug/src/crt0scrm.s b/doug/src/crt0scrm.s deleted file mode 100755 index b787bde5..00000000 --- a/doug/src/crt0scrm.s +++ /dev/null @@ -1,44 +0,0 @@ -;-------------------------------------------------------------------------- -; crt0scrm.s 8/7/2011 dwg - - Generic crt0.s for a Z80 with jump loop -;-------------------------------------------------------------------------- - - - .area _HEADER (ABS) - .org 0 - - .include "scsi2ide.inc" - .include "ns16550.inc" - -scream: - - ld a,#UART_DLAB - out (wUART_LCR),a - - ld a,#0x00 - out (wUART_DIV_HI),a - - ld a,#UART_BAUD_9600 - out (wUART_DIV_LO),a - - ld a,#0 - out (wUART_LCR),a - - ld a,#0x03 - out (wUART_LCR),a - - ld a,#0x03 - out (wUART_MCR),a - -scrmlp: - in a,(rUART_LSR) - and a,#UART_TBE - jp z,scrmlp - - ld a,#0x30 ; ascii 0 (zero) - out (wUART_TDR),a - - jp scrmlp - - - - diff --git a/doug/src/crt0scrm.sym b/doug/src/crt0scrm.sym deleted file mode 100644 index adeabd9e..00000000 --- a/doug/src/crt0scrm.sym +++ /dev/null @@ -1,18 +0,0 @@ - ASxxxx Assembler V02.00 + NoICE + SDCC mods + Flat24 (Zilog Z80 / Hitachi HD64180), page 1. - -Symbol Table - - .__.ABS.= 0000 G | SCSI2IDE= 0000 | UART_BAU= 000C - UART_DLA= 0080 | UART_IO_= 0010 | UART_RDA= 0001 - UART_TBE= 0020 | rUART_II= 0012 | rUART_LS= 0015 - rUART_MS= 0016 | rUART_RD= 0010 | 2 scream 0000 R - 2 scrmlp 0018 R | wUART_DI= 0011 | wUART_DI= 0010 - wUART_FC= 0017 | wUART_IE= 0011 | wUART_LC= 0013 - wUART_MC= 0014 | wUART_TD= 0010 - ASxxxx Assembler V02.00 + NoICE + SDCC mods + Flat24 (Zilog Z80 / Hitachi HD64180), page 2. - -Area Table - - 0 _CODE size 0 flags 0 - 1 _HEADER size 0 flags 8 - 2 _HEADER0 size 26 flags 8 diff --git a/doug/src/dbgmon.arf b/doug/src/dbgmon.arf deleted file mode 100755 index 4db7f615..00000000 --- a/doug/src/dbgmon.arf +++ /dev/null @@ -1,6 +0,0 @@ --mjx --i dbgmon.ihx --k /usr/local/share/sdcc/lib/z80 --l z80 -dbgmon.rel --e diff --git a/doug/src/dbgmon.lst b/doug/src/dbgmon.lst deleted file mode 100755 index ed616c0e..00000000 --- a/doug/src/dbgmon.lst +++ /dev/null @@ -1,1909 +0,0 @@ - 1 .title dbgmon.s derived from dbgmon.asm - 2 .sbttl Ported by Douglas Goodall - 3 - 4 .module dbgmon - 5 .optsdcc -mz80 - 6 - 7 ;-------------------------------------------------------- - 8 ; Public variables in this module - 9 ;-------------------------------------------------------- - 10 .globl _dbgmon - 11 ;-------------------------------------------------------- - 12 ; special function registers - 13 ;-------------------------------------------------------- - 14 ;-------------------------------------------------------- - 15 ; ram data - 16 ;-------------------------------------------------------- - 17 .area _DATA - 18 ;-------------------------------------------------------- - 19 ; overlayable items in ram - 20 ;-------------------------------------------------------- - 21 .area _OVERLAY - 22 ;-------------------------------------------------------- - 23 ; external initialized ram data - 24 ;-------------------------------------------------------- - 25 ;-------------------------------------------------------- - 26 ; global & static initialisations - 27 ;-------------------------------------------------------- - 28 .area _HOME - 29 .area _GSINIT - 30 .area _GSFINAL - 31 .area _GSINIT - 32 ;-------------------------------------------------------- - 33 ; Home - 34 ;-------------------------------------------------------- - 35 .area _HOME - 36 .area _HOME - 37 ;-------------------------------------------------------- - 38 ; code - 39 ;-------------------------------------------------------- - 40 .area _DBGMON - 0000 41 _dbgmon_start:: - 0000 42 _dbgmon: - 43 - 44 - 45 ;___ROM_MONITOR_PROGRAM_____________________________________________________________________________________________________________ - 46 ; - 47 ; ORIGINAL CODE BY: ANDREW LYNCH (LYNCHAJ@YAHOO COM) 13 FEB 2007 - 48 ; - 49 ; MODIFIED BY : DAN WERNER 03 09.2009 - 50 ; - 51 ;__REFERENCES________________________________________________________________________________________________________________________ - 52 ; THOMAS SCHERRER BASIC HAR.DWARE TEST ASSEMBLER SOURCES FROM THE Z80 INFO PAGE - 53 ; INCLUDING ORIGINAL SCHEMATIC CONCEPT - 54 ; HTTP://Z80 INFO/Z80SOURC.TXT - 55 ; CODE SAMPLES FROM BRUCE JONES PUBLIC DOMAIN ROM MONITOR FOR THE SBC-200C - 56 ; HTTP://WWW RETROTECHNOLOGY.COM/HERBS_STUFF/SD_BRUCE_CODE.ZIP - 57 ; INSPIRATION FROM JOEL OWENS "Z-80 SPACE-TIME PRODUCTIONS SINGLE BOARD COMPUTER" - 58 ; HTTP://WWW JOELOWENS.ORG/Z80/Z80INDEX.HTML - 59 ; GREAT HELP AND TECHNICAL ADVICE FROM ALLISON AT ALPACA_DESIGNERS - 60 ; HTTP://GROUPS YAHOO.COM/GROUP/ALPACA_DESIGNERS - 61 ; INTEL SDK-85 ROM DEBUG MONITOR - 62 ; - 63 ;__HARDWARE_INTERFACES________________________________________________________________________________________________________________ - 64 ; - 65 ; PIO 82C55 I/O IS DECODED TO PORT 60-67 - 66 ; - 0060 67 PORTA = 0x60 - 0061 68 PORTB = 0x61 - 0062 69 PORTC = 0x62 - 0063 70 PIOCONT = 0x63 - 71 ; - 72 ; UART 16C450 SERIAL IS DECODED TO 68-6F - 73 ; - 0068 74 UART0 = 0x68 ; DATA IN/OUT - 0069 75 UART1 = 0x69 ; CHECK RX - 006A 76 UART2 = 0x6A ; INTERRUPTS - 006B 77 UART3 = 0x6B ; LINE CONTROL - 006C 78 UART4 = 0x6C ; MODEM CONTROL - 006D 79 UART5 = 0x6D ; LINE STATUS - 006E 80 UART6 = 0x6E ; MODEM STATUS - 006F 81 UART7 = 0x6F ; SCRATCH REG. - 82 ; - 83 ; MEMORY PAGE CONFIGURATION LATCH IS DECODED TO 78 - 84 ; - 0078 85 MPCL = 0x78 ; CONTROL PORT, SHOULD ONLY BE CHANGED WHILE - 86 ; IN UPPER MEMORY PAGE 08000h-$FFFF OR LIKELY - 0078 87 MPCL_RAM = 0x78 ; BASE IO ADDRESS OF RAM MEMORY PAGER CONFIGURATION LATCH - 007C 88 MPCL_ROM = 0x7C ; BASE IO ADDRESS OF ROM MEMORY PAGER CONFIGURATION LATCH - 89 ; LOSS OF CPU MEMORY CONTEXT - 90 ; - 91 ; MEMORY PAGE CONFIGURATION LATCH CONTROL PORT ( IO_Y3 ) INFORMATION - 92 ; - 93 ; 7 6 5 4 3 2 1 0 ONLY APPLICABLE TO THE LOWER MEMORY PAGE 00000h-$7FFF - 94 ; ^ ^ ^ ^ ^ ^ ^ ^ - 95 ; : : : : : : : :--0 = A15 RAM/ROM ADDRESS LINE DEFAULT IS 0 - 96 ; : : : : : : :----0 = A16 RAM/ROM ADDRESS LINE DEFAULT IS 0 - 97 ; : : : : : :------0 = A17 RAM/ROM ADDRESS LINE DEFAULT IS 0 - 98 ; : : : : :--------0 = A18 RAM/ROM ADDRESS LINE DEFAULT IS 0 - 99 ; : : : :-----------0 = A19 ROM ONLY ADDRESS LINE DEFAULT IS 0 - 100 ; : : :-------------0 = - 101 ; : :---------------0 = - 102 ; :-----------------0 = ROM SELECT (0=ROM, 1=RAM) DEFAULT IS 0 - 103 ; - 104 ; - 105 ;IDE REGISTER IO PORT ; FUNCTION - 0020 106 IDELO = 0x020 ; DATA PORT (LOW BYTE) - 0021 107 IDEERR = 0x021 ; READ: ERROR REGISTER; WRITE: PRECOMP - 0022 108 IDESECTC = 0x022 ; SECTOR COUNT - 0023 109 IDESECTN = 0x023 ; SECTOR NUMBER - 0024 110 IDECYLLO = 0x024 ; CYLINDER LOW - 0025 111 IDECYLHI = 0x025 ; CYLINDER HIGH - 0026 112 IDEHEAD = 0x026 ; DRIVE/HEAD - 0027 113 IDESTTS = 0x027 ; READ: STATUS; WRITE: COMMAND - 0028 114 IDEHI = 0x028 ; DATA PORT (HIGH BYTE) - 002E 115 IDECTRL = 0x02E ; READ: ALTERNATIVE STATUS; WRITE; DEVICE CONTROL - 002F 116 IDEADDR = 0x02F ; DRIVE ADDRESS (READ ONLY) - 117 - 118 ; - 119 ; - 120 ;__CONSTANTS_________________________________________________________________________________________________________________________ - 121 ; - FFFF 122 RAMTOP = 0x0FFFF ; HIGHEST ADDRESSABLE MEMORY LOCATION - CFFF 123 STACKSTART = 0x0CFFF ; START OF STACK - 8000 124 RAMBOTTOM = 0x08000 ; START OF FIXED UPPER 32K PAGE OF 512KB X 8 RAM 8000H-FFFFH - 8000 125 MONSTARTCOLD = 0x08000 ; COLD START MONITOR IN HIGH RAM - 00FF 126 ENDT = 0x0FF ; MARK END OF TEXT - 000D 127 CR = 0x0D ; ASCII CARRIAGE RETURN CHARACTER - 000A 128 LF = 0x0A ; ASCII LINE FEED CHARACTER - 001B 129 ESC = 0x1B ; ASCII ESCAPE CHARACTER - 0008 130 BS = 0x08 ; ASCII BACKSPACE CHARACTER - 131 - 0041 132 ASCIIA = 0x41 - 0042 133 ASCIIB = 0x42 - 0043 134 ASCIIC = 0x43 - 0044 135 ASCIID = 0x44 - 0045 136 ASCIIE = 0x45 - 0046 137 ASCIIF = 0x46 - 0047 138 ASCIIG = 0x47 - 0048 139 ASCIIH = 0x48 - 0049 140 ASCIII = 0x49 - 004A 141 ASCIIJ = 0x4A - 004B 142 ASCIIK = 0x4B - 004C 143 ASCIIL = 0x4C - 004D 144 ASCIIM = 0x4D - 004E 145 ASCIIN = 0x4E - 004F 146 ASCIIO = 0x4F - 0050 147 ASCIIP = 0x50 - 0051 148 ASCIIQ = 0x51 - 0052 149 ASCIIR = 0x52 - 0053 150 ASCIIS = 0x53 - 0054 151 ASCIIT = 0x54 - 0055 152 ASCIIU = 0x55 - 0056 153 ASCIIV = 0x56 - 0057 154 ASCIIW = 0x57 - 0058 155 ASCIIX = 0x58 - 0059 156 ASCIIY = 0x59 - 005A 157 ASCIIZ = 0x5A - 158 - 159 ; - 160 ; - 161 ; - 162 ;__MAIN_PROGRAM_____________________________________________________________________________________________________________________ - 163 ; - 164 ; ORG 00100h ; FOR DEBUG IN CP/M (AS .COM) - 165 - 166 ;dwg; .ORG 8000H ; NORMAL OP - 167 - 0000 31 FF CF 168 LD SP,#STACKSTART ; SET THE STACK POINTER TO STACKSTART - 0003 CDr32s06 169 CALL INITIALIZE ; INITIALIZE SYSTEM - 170 - 171 - 172 - 173 ;__FRONT_PANEL_STARTUP___________________________________________________________________________________________________________ - 174 ; - 175 ; START UP THE SYSTEM WITH THE FRONT PANEL INTERFACE - 176 ; - 177 ;________________________________________________________________________________________________________________________________ - 178 ; - 0006 CDr3Bs06 179 CALL MTERM_INIT ; INIT 8255 FOR MTERM - 0009 21rC7s0C 180 LD HL,#CPUUP ; SET POINTER TO DATA BUFFER - 000C CDr05s07 181 CALL SEGDISPLAY ; DISPLAY - 182 - 183 - 184 - 000F 185 FRONTPANELLOOP: - 000F CDr40s06 186 CALL KB_GET ; GET KEY FROM KB - 187 - 0012 FE 10 188 CP #0x10 ; IS PORT READ? - 0014 CAr3Cs00 189 JP Z,DOPORTREAD ; YES, JUMP - 0017 FE 11 190 CP #0x11 ; IS PORT WRITE? - 0019 CAr94s00 191 JP Z,DOPORTWRITE ; YES, JUMP - 001C FE 14 192 CP #0x14 ; IS DEPOSIT? - 001E CArD0s00 193 JP Z,DODEPOSIT ; YES, JUMP - 0021 FE 15 194 CP #0x15 ; IS EXAMINE? - 0023 CAr24s01 195 JP Z,DOEXAMINE ; YES, JUMP - 0026 FE 16 196 CP #0x16 ; IS GO? - 0028 CArCCs00 197 JP Z,DOGO ; YES, JUMP - 002B FE 17 198 CP #0x17 ; IS BO? - 002D CAr33s00 199 JP Z,DOBOOT ; YES, JUMP - 200 - 0030 18 DD 201 JR FRONTPANELLOOP ; LOOP - 0032 202 EXIT: - 0032 C9 203 RET - 204 - 205 - 206 ;__DOBOOT________________________________________________________________________________________________________________________ - 207 ; - 208 ; PERFORM BOOT FRONT PANEL ACTION - 209 ;________________________________________________________________________________________________________________________________ - 210 ; - 0033 211 DOBOOT: - 0033 3E 00 212 LD A,#0 ; LOAD VALUE TO SWITCH OUT ROM - 0035 D3 7C 213 OUT (MPCL_ROM),A ; SWITCH OUT ROM, BRING IN LOWER 32K RAM PAGE - 214 ; - 215 ; - 0037 D3 78 216 OUT (MPCL_RAM),A ; - 0039 C3 00 00 217 JP 0 ; GO TO CP/M - 218 - 219 - 220 ;__DOPORTREAD____________________________________________________________________________________________________________________ - 221 ; - 222 ; PERFORM PORT READ FRONT PANEL ACTION - 223 ;________________________________________________________________________________________________________________________________ - 224 ; - 003C 225 DOPORTREAD: - 003C CDr6Cs02 226 CALL GETPORT ; GET PORT INTO A - 003F 227 PORTREADLOOP: - 003F 4F 228 LD C,A ; STORE PORT IN "C" - 0040 CB 3F 229 SRL A ; ROTATE HIGH NIB TO LOW - 0042 CB 3F 230 SRL A ; - 0044 CB 3F 231 SRL A ; - 0046 CB 3F 232 SRL A ; - 0048 32r90s07 233 LD (DISPLAYBUF+5),A ; SHOW HIGH NIB IN DISP 5 - 004B 79 234 LD A,C ; RESTORE PORT VALUE INTO "A" - 004C E6 0F 235 AND #0x0F ; CLEAR HIGH NIB, LEAVING LOW - 004E 32r8Fs07 236 LD (DISPLAYBUF+4),A ; SHOW LOW NIB IN DISP 4 - 0051 ED 78 237 IN A,(C) ; GET PORT VALUE FROM PORT IN "C" - 0053 4F 238 LD C,A ; STORE VALUE IN "C" - 0054 CB 3F 239 SRL A ; ROTATE HIGH NIB TO LOW - 0056 CB 3F 240 SRL A ; - 0058 CB 3F 241 SRL A ; - 005A CB 3F 242 SRL A ; - 005C 32r8Cs07 243 LD (DISPLAYBUF+1),A ; SHOW HIGH NIB IN DISP 1 - 005F 79 244 LD A,C ; RESTORE VALUE TO "A" - 0060 E6 0F 245 AND #0x0F ; CLEAR HIGH NIB, LEAVING LOW - 0062 32r8Bs07 246 LD (DISPLAYBUF),A ; DISPLAY LOW NIB IN DISP 0 - 0065 3E 10 247 LD A,#0x10 ; CLEAR OTHER DISPLAYS - 0067 32r8Ds07 248 LD (DISPLAYBUF+2),A ; - 006A 32r8Es07 249 LD (DISPLAYBUF+3),A ; - 006D 3E 13 250 LD A,#0x13 ; "P" - 006F 32r92s07 251 LD (DISPLAYBUF+7),A ; STORE IN DISP 7 - 0072 3E 14 252 LD A,#0x14 ; "O" - 0074 32r91s07 253 LD (DISPLAYBUF+6),A ; STORE IN DISP 6 - 0077 21r8Bs07 254 LD HL,#DISPLAYBUF ; SET POINTER TO DISPLAY BUFFER - 007A CDrBEs06 255 CALL HEXDISPLAY ; DISPLAY BUFFER CONTENTS - 007D 256 PORTREADGETKEY: - 007D CDr40s06 257 CALL KB_GET ; GET KEY FROM KB - 0080 FE 12 258 CP #0x12 ; [CL] PRESSED, EXIT - 0082 CAr8Bs00 259 JP Z,PORTREADEXIT ; - 0085 FE 10 260 CP #0x10 ; [PR] PRESSED, PROMPT FOR NEW PORT - 0087 28 B3 261 JR Z,DOPORTREAD ; - 0089 18 F2 262 JR PORTREADGETKEY ; NO VALID KEY, LOOP - 008B 263 PORTREADEXIT: - 008B 21rC7s0C 264 LD HL,#CPUUP ; SET POINTER TO DATA BUFFER - 008E CDr05s07 265 CALL SEGDISPLAY ; DISPLAY - 0091 C3r0Fs00 266 JP FRONTPANELLOOP ; - 267 - 268 ;__DOPORTWRITE____________________________________________________________________________________________________________________ - 269 ; - 270 ; PERFORM PORT WRITE FRONT PANEL ACTION - 271 ;________________________________________________________________________________________________________________________________ - 272 ; - 0094 273 DOPORTWRITE: - 0094 CDr6Cs02 274 CALL GETPORT ; GET PORT INTO A - 0097 275 PORTWRITELOOP: - 0097 4F 276 LD C,A ; STORE PORT IN "C" - 0098 CB 3F 277 SRL A ; ROTATE HIGH NIB INTO LOW - 009A CB 3F 278 SRL A ; - 009C CB 3F 279 SRL A ; - 009E CB 3F 280 SRL A ; - 00A0 32r90s07 281 LD (DISPLAYBUF+5),A ; DISPLAY HIGH NIB IN DISPLAY 5 - 00A3 79 282 LD A,C ; RESTORE PORT VALUE INTO "A" - 00A4 E6 0F 283 AND #0x0F ; CLEAR OUT HIGH NIB - 00A6 32r8Fs07 284 LD (DISPLAYBUF+4),A ; DISPLAY LOW NIB IN DISPLAY 4 - 00A9 3E 10 285 LD A,#0x10 ; CLEAR OUT DISPLAYS 2 AND 3 - 00AB 32r8Ds07 286 LD (DISPLAYBUF+2),A ; - 00AE 32r8Es07 287 LD (DISPLAYBUF+3),A ; - 00B1 3E 13 288 LD A,#0x13 ; DISPLAY "P" IN DISP 7 - 00B3 32r92s07 289 LD (DISPLAYBUF+7),A ; - 00B6 3E 14 290 LD A,#0x14 ; DISPLAY "O" IN DISP 6 - 00B8 32r91s07 291 LD (DISPLAYBUF+6),A ; - 00BB 21r8Bs07 292 LD HL,#DISPLAYBUF ; POINT TO DISPLAY BUFFER - 00BE CDrCFs02 293 CALL GETVALUE ; INPUT A BYTE VALUE, RETURN IN "A" - 00C1 ED 79 294 OUT (C),A ; OUTPUT VALUE TO PORT STORED IN "C" - 00C3 21rC7s0C 295 LD HL,#CPUUP ; SET POINTER TO DATA BUFFER - 00C6 CDr05s07 296 CALL SEGDISPLAY ; DISPLAY - 00C9 C3r0Fs00 297 JP FRONTPANELLOOP ; - 298 - 299 - 300 ;__DOGO__________________________________________________________________________________________________________________________ - 301 ; - 302 ; PERFORM GO FRONT PANEL ACTION - 303 ;________________________________________________________________________________________________________________________________ - 304 ; - 00CC 305 DOGO: - 00CC CDr89s01 306 CALL GETADDR ; GET ADDRESS INTO HL - 00CF E9 307 JP (HL) ; GO THERE! - 308 - 309 - 310 - 311 ;__DODEPOSIT________________________________________________________________________________________________________________________ - 312 ; - 313 ; PERFORM DEPOSIT FRONT PANEL ACTION - 314 ;________________________________________________________________________________________________________________________________ - 315 ; - 00D0 316 DODEPOSIT: - 00D0 CDr89s01 317 CALL GETADDR ; GET ADDRESS INTO HL - 00D3 E5 318 PUSH HL - 00D4 319 DEPOSITLOOP: - 00D4 7C 320 LD A,H ; - 00D5 CB 3F 321 SRL A ; - 00D7 CB 3F 322 SRL A ; - 00D9 CB 3F 323 SRL A ; - 00DB CB 3F 324 SRL A ; - 00DD 32r92s07 325 LD (DISPLAYBUF+7),A ; - 00E0 7C 326 LD A,H ; - 00E1 E6 0F 327 AND #0x0F ; - 00E3 32r91s07 328 LD (DISPLAYBUF+6),A ; - 00E6 7D 329 LD A,L ; - 00E7 CB 3F 330 SRL A ; - 00E9 CB 3F 331 SRL A ; - 00EB CB 3F 332 SRL A ; - 00ED CB 3F 333 SRL A ; - 00EF 32r90s07 334 LD (DISPLAYBUF+5),A ; - 00F2 7D 335 LD A,L ; - 00F3 E6 0F 336 AND #0x0F ; - 00F5 32r8Fs07 337 LD (DISPLAYBUF+4),A ; - 00F8 3E 10 338 LD A,#0x10 ; - 00FA 32r8Es07 339 LD (DISPLAYBUF+3),A ; - 00FD 21r8Bs07 340 LD HL,#DISPLAYBUF ; - 0100 CDrCFs02 341 CALL GETVALUE ; - 0103 E1 342 POP HL ; - 0104 77 343 LD (HL),A ; - 0105 344 DEPOSITGETKEY: - 0105 CDr40s06 345 CALL KB_GET ; GET KEY FROM KB - 0108 FE 12 346 CP #0x12 ; [CL] PRESSED, EXIT - 010A CAr1Bs01 347 JP Z,DEPOSITEXIT ; - 010D FE 13 348 CP #0x13 ; [EN] PRESSED, INC ADDRESS AND LOOP - 010F 28 06 349 JR Z,DEPOSITFW ; - 0111 FE 14 350 CP #0x14 ; [DE] PRESSED, PROMPT FOR NEW ADDRESS - 0113 28 BB 351 JR Z,DODEPOSIT ; - 0115 18 EE 352 JR DEPOSITGETKEY ; NO VALID KEY, LOOP - 0117 353 DEPOSITFW: - 0117 23 354 INC HL ; - 0118 E5 355 PUSH HL ; STORE HL - 0119 18 B9 356 JR DEPOSITLOOP ; - 011B 357 DEPOSITEXIT: - 011B 21rC7s0C 358 LD HL,#CPUUP ; SET POINTER TO DATA BUFFER - 011E CDr05s07 359 CALL SEGDISPLAY ; DISPLAY - 0121 C3r0Fs00 360 JP FRONTPANELLOOP ; - 361 - 362 - 363 - 364 - 365 ;__DOEXAMINE________________________________________________________________________________________________________________________ - 366 ; - 367 ; PERFORM EXAMINE FRONT PANEL ACTION - 368 ;________________________________________________________________________________________________________________________________ - 369 ; - 0124 370 DOEXAMINE: - 0124 CDr89s01 371 CALL GETADDR ; GET ADDRESS INTO HL - 0127 E5 372 PUSH HL ; STORE HL - 0128 373 EXAMINELOOP: - 0128 7C 374 LD A,H ; MOVE HIGH BYTE IN "A" - 0129 CB 3F 375 SRL A ; SHOW HIGH NIBBLE IN DISP 7 - 012B CB 3F 376 SRL A ; - 012D CB 3F 377 SRL A ; - 012F CB 3F 378 SRL A ; - 0131 32r92s07 379 LD (DISPLAYBUF+7),A ; - 0134 7C 380 LD A,H ; RESTORE HIGH BYTE - 0135 E6 0F 381 AND #0x0F ; CLEAR HIGH NIBBLE - 0137 32r91s07 382 LD (DISPLAYBUF+6),A ; DISPLAY LOW NIBBLE IN DISP 6 - 013A 7D 383 LD A,L ; PUT LOW BYTE IN "A" - 013B CB 3F 384 SRL A ; SHOW HIGH NIBBLE IN DISP 5 - 013D CB 3F 385 SRL A ; - 013F CB 3F 386 SRL A ; - 0141 CB 3F 387 SRL A ; - 0143 32r90s07 388 LD (DISPLAYBUF+5),A ; - 0146 7D 389 LD A,L ; RESTORE LOW BYTE IN "A" - 0147 E6 0F 390 AND #0x0F ; CLEAR OUT HIGH NIBBLE - 0149 32r8Fs07 391 LD (DISPLAYBUF+4),A ; DISPLAY LOW NIBBLE IN DISP 4 - 014C 3E 10 392 LD A,#0x10 ; CLEAR OUT DISP 3 - 014E 32r8Es07 393 LD (DISPLAYBUF+3),A ; - 0151 7E 394 LD A,(HL) ; GET VALUE FROM ADDRESS IN HL - 0152 CB 3F 395 SRL A ; DISPLAY HIGH NIB IN DISPLAY 1 - 0154 CB 3F 396 SRL A ; - 0156 CB 3F 397 SRL A ; - 0158 CB 3F 398 SRL A ; - 015A 32r8Cs07 399 LD (DISPLAYBUF+1),A ; - 015D 7E 400 LD A,(HL) ; GET VALUE FROM ADDRESS IN HL - 015E E6 0F 401 AND #0x0F ; CLEAR OUT HIGH NIBBLE - 0160 32r8Bs07 402 LD (DISPLAYBUF),A ; DISPLAY LOW NIBBLE IN DISPLAY 0 - 0163 21r8Bs07 403 LD HL,#DISPLAYBUF ; POINT TO DISPLAY BUFFER - 0166 CDrBEs06 404 CALL HEXDISPLAY ; DISPLAY BUFFER ON DISPLAYS - 0169 E1 405 POP HL ; RESTORE HL - 016A 406 EXAMINEGETKEY: - 016A CDr40s06 407 CALL KB_GET ; GET KEY FROM KB - 016D FE 12 408 CP #0x12 ; [CL] PRESSED, EXIT - 016F CAr80s01 409 JP Z,EXAMINEEXIT ; - 0172 FE 13 410 CP #0x13 ; [EN] PRESSED, INC ADDRESS AND LOOP - 0174 28 06 411 JR Z,EXAMINEFW ; - 0176 FE 15 412 CP #0x15 ; [DE] PRESSED, PROMPT FOR NEW ADDRESS - 0178 28 AA 413 JR Z,DOEXAMINE ; - 017A 18 EE 414 JR EXAMINEGETKEY ; NO VALID KEY, LOOP - 017C 415 EXAMINEFW: - 017C 23 416 INC HL ; HL++ - 017D E5 417 PUSH HL ; STORE HL - 017E 18 A8 418 JR EXAMINELOOP ; - 0180 419 EXAMINEEXIT: - 0180 21rC7s0C 420 LD HL,#CPUUP ; SET POINTER TO DATA BUFFER - 0183 CDr05s07 421 CALL SEGDISPLAY ; DISPLAY - 0186 C3r0Fs00 422 JP FRONTPANELLOOP ; - 423 - 424 - 425 ;__GETADDR_______________________________________________________________________________________________________________________ - 426 ; - 427 ; GET ADDRESS FROM FRONT PANEL - 428 ;________________________________________________________________________________________________________________________________ - 429 ; - 0189 430 GETADDR: - 0189 C5 431 PUSH BC ; STORE BC - 018A 18 6A 432 JR GETADDRCLEAR ; - 018C 433 GETADDR1: - 018C 21rCFs0C 434 LD HL,#ADDR ; DISPLAY PROMPT - 018F CDr05s07 435 CALL SEGDISPLAY ; - 0192 436 GETADDRLOOP: - 0192 CDr40s06 437 CALL KB_GET ; - 0195 FE 10 438 CP #0x10 ; - 0197 FArDDs01 439 JP M,GETADDRNUM ; NUMBER PRESSED, STORE IT - 019A FE 13 440 CP #0x13 ; EN PRESSED, DONE - 019C 28 06 441 JR Z,GETADDRDONE ; - 019E FE 12 442 CP #0x12 ; CLEAR PRESSED, CLEAR - 01A0 28 54 443 JR Z,GETADDRCLEAR ; - 01A2 18 EE 444 JR GETADDRLOOP ; INVALID KEY, LOOP - 01A4 445 GETADDRDONE: - 01A4 21 00 00 446 LD HL,#0 ; HL=0 - 01A7 3Ar8Cs07 447 LD A,(DISPLAYBUF+1) ; GET DIGIT IN DISPLAY 1 - 01AA CB 27 448 SLA A ; ROTATE IT TO HIGH NIBBLE - 01AC CB 27 449 SLA A ; - 01AE CB 27 450 SLA A ; - 01B0 CB 27 451 SLA A ; - 01B2 4F 452 LD C,A ; STORE IT IN "C" - 01B3 3Ar8Bs07 453 LD A,(DISPLAYBUF) ; GET DIGIT IN DISPLAY 0 - 01B6 E6 0F 454 AND #0x0F ; CLEAR HIGH NIBBLE - 01B8 B1 455 OR C ; ADD IN NIBBLE STORED IN C - 01B9 6F 456 LD L,A ; STORE IT IN LOW BYTE OF ADDRESS POINTER - 01BA 3Ar8Es07 457 LD A,(DISPLAYBUF+3) ; GET DIGIT IN DISPLAY 3 - 01BD CB 27 458 SLA A ; ROTATE IT TO HIGH NIBBLE - 01BF CB 27 459 SLA A ; - 01C1 CB 27 460 SLA A ; - 01C3 CB 27 461 SLA A ; - 01C5 4F 462 LD C,A ; STORE IT IN "C" - 01C6 3Ar8Ds07 463 LD A,(DISPLAYBUF+2) ; GET DIGIT IN DISPLAY 2 - 01C9 E6 0F 464 AND #0x0F ; CLEAR HIGH NIBBLE - 01CB B1 465 OR C ; ADD IN NIBBLE STORED IN "C" - 01CC 67 466 LD H,A ; STORE BYTE IN HIGH BYTE OF ADDRESS POINTER - 01CD 3E 10 467 LD A,#0x10 ; CLEAR OUT DISPLAYS 0,1,2 & 3 - 01CF 32r8Bs07 468 LD (DISPLAYBUF),A ; - 01D2 32r8Cs07 469 LD (DISPLAYBUF+1),A ; - 01D5 32r8Ds07 470 LD (DISPLAYBUF+2),A ; - 01D8 32r8Es07 471 LD (DISPLAYBUF+3),A ; - 01DB C1 472 POP BC ; RESTORE BC - 01DC C9 473 RET - 01DD 474 GETADDRNUM: - 01DD 4F 475 LD C,A ; - 01DE 3Ar8Ds07 476 LD A,(DISPLAYBUF+2) ; SHIFT BYTES IN DISPLAY BUF TO THE LEFT - 01E1 32r8Es07 477 LD (DISPLAYBUF+3),A ; - 01E4 3Ar8Cs07 478 LD A,(DISPLAYBUF+1) ; - 01E7 32r8Ds07 479 LD (DISPLAYBUF+2),A ; - 01EA 3Ar8Bs07 480 LD A,(DISPLAYBUF) ; - 01ED 32r8Cs07 481 LD (DISPLAYBUF+1),A ; - 01F0 79 482 LD A,C ; DISPLAY KEYSTROKE IN RIGHT MOST DISPLAY (0) - 01F1 32r8Bs07 483 LD (DISPLAYBUF+0),A ; - 01F4 18 0E 484 JR GETADDRDISP ; - 01F6 485 GETADDRCLEAR: - 01F6 3E 12 486 LD A,#0x12 ; CLEAR OUT DISPLAYS 0,1,2 & 3 - 01F8 32r8Bs07 487 LD (DISPLAYBUF),A ; - 01FB 32r8Cs07 488 LD (DISPLAYBUF+1),A ; - 01FE 32r8Ds07 489 LD (DISPLAYBUF+2),A ; - 0201 32r8Es07 490 LD (DISPLAYBUF+3),A ; - 0204 491 GETADDRDISP: - 0204 3Ar8Bs07 492 LD A,(DISPLAYBUF) ; ENCODE DIGITS IN DISPLAY BUFFER TO DISPLAY - 0207 CDrF8s06 493 CALL DECODEDISPLAY ; - 020A 32rCFs0C 494 LD (ADDR),A ; - 020D 3Ar8Cs07 495 LD A,(DISPLAYBUF+1) ; - 0210 CDrF8s06 496 CALL DECODEDISPLAY ; - 0213 32rD0s0C 497 LD (ADDR+1),A ; - 0216 3Ar8Ds07 498 LD A,(DISPLAYBUF+2) ; - 0219 CDrF8s06 499 CALL DECODEDISPLAY ; - 021C 32rD1s0C 500 LD (ADDR+2),A ; - 021F 3Ar8Es07 501 LD A,(DISPLAYBUF+3) ; - 0222 CDrF8s06 502 CALL DECODEDISPLAY ; - 0225 32rD2s0C 503 LD (ADDR+3),A ; - 0228 C3r8Cs01 504 JP GETADDR1 ; - 505 - 506 - 507 - 508 ;__DSPSECTOR_______________________________________________________________________________________________________________________ - 509 ; - 510 ; DISPLAY SECTOR IN HL ON FRONT PANEL - 511 ;________________________________________________________________________________________________________________________________ - 512 ; - 022B 513 DSPSECTOR: - 022B C5 514 PUSH BC ; STORE BC - 022C E5 515 PUSH HL ; STORE HL - 022D 7C 516 LD A,H ; DISPLAY HIGH BYTE, HIGH NIBBLE - 022E CB 3F 517 SRL A ; - 0230 CB 3F 518 SRL A ; - 0232 CB 3F 519 SRL A ; - 0234 CB 3F 520 SRL A ; - 0236 E6 0F 521 AND #0x0F ; - 0238 CDrF8s06 522 CALL DECODEDISPLAY ; - 023B 32rE2s0C 523 LD (SEC+3),A ; - 023E 7C 524 LD A,H ; DISPLAY HIGH BYTE, LOW NIBBLE - 023F E6 0F 525 AND #0x0F ; - 0241 CDrF8s06 526 CALL DECODEDISPLAY ; - 0244 32rE1s0C 527 LD (SEC+2),A ; - 0247 7D 528 LD A,L ; DISPLAY LOW BYTE, HIGH NIBBLE - 0248 E6 F0 529 AND #0x0F0 ; - 024A CB 3F 530 SRL A ; - 024C CB 3F 531 SRL A ; - 024E CB 3F 532 SRL A ; - 0250 CB 3F 533 SRL A ; - 0252 E6 0F 534 AND #0x0F ; - 0254 CDrF8s06 535 CALL DECODEDISPLAY ; - 0257 32rE0s0C 536 LD (SEC+1),A ; DISPLAY LOW BYTE, LOW NIBBLE - 025A 7D 537 LD A,L ; - 025B E6 0F 538 AND #0x0F ; - 025D CDrF8s06 539 CALL DECODEDISPLAY ; - 0260 32rDFs0C 540 LD (SEC),A ; - 0263 21rDFs0C 541 LD HL,#SEC ; DISPLAY PROMPT - 0266 CDr05s07 542 CALL SEGDISPLAY ; - 0269 E1 543 POP HL ; RESTORE HL - 026A C1 544 POP BC ; RESTORE BC - 026B C9 545 RET - 546 - 547 - 548 - 549 ;__GETPORT_______________________________________________________________________________________________________________________ - 550 ; - 551 ; GET PORT FROM FRONT PANEL - 552 ;________________________________________________________________________________________________________________________________ - 553 ; - 026C 554 GETPORT: - 026C C5 555 PUSH BC ; STORE BC - 026D 18 43 556 JR GETPORTCLEAR ; - 026F 557 GETPORT1: - 026F 21rD7s0C 558 LD HL,#PORT ; DISPLAY PROMPT - 0272 CDr05s07 559 CALL SEGDISPLAY ; - 0275 560 GETPORTLOOP: - 0275 CDr40s06 561 CALL KB_GET ; - 0278 FE 10 562 CP #0x10 ; - 027A FArA5s02 563 JP M,GETPORTNUM ; NUMBER PRESSED, STORE IT - 027D FE 13 564 CP #0x13 ; EN PRESSED, DONE - 027F 28 06 565 JR Z,GETPORTDONE ; - 0281 FE 12 566 CP #0x12 ; CLEAR PRESSED, CLEAR - 0283 28 2D 567 JR Z,GETPORTCLEAR ; - 0285 18 EE 568 JR GETPORTLOOP ; INVALID KEY, LOOP - 0287 569 GETPORTDONE: - 0287 3Ar8Cs07 570 LD A,(DISPLAYBUF+1) ; - 028A CB 27 571 SLA A ; - 028C CB 27 572 SLA A ; - 028E CB 27 573 SLA A ; - 0290 CB 27 574 SLA A ; - 0292 4F 575 LD C,A ; - 0293 3Ar8Bs07 576 LD A,(DISPLAYBUF) ; - 0296 E6 0F 577 AND #0x0F ; - 0298 B1 578 OR C ; - 0299 4F 579 LD C,A ; - 029A 3E 10 580 LD A,#0x10 ; - 029C 32r8Bs07 581 LD (DISPLAYBUF),A ; - 029F 32r8Cs07 582 LD (DISPLAYBUF+1),A ; - 02A2 79 583 LD A,C ; - 02A3 C1 584 POP BC ; RESTORE BC - 02A4 C9 585 RET - 02A5 586 GETPORTNUM: - 02A5 4F 587 LD C,A ; - 02A6 3Ar8Bs07 588 LD A,(DISPLAYBUF) ; - 02A9 32r8Cs07 589 LD (DISPLAYBUF+1),A ; - 02AC 79 590 LD A,C ; - 02AD 32r8Bs07 591 LD (DISPLAYBUF+0),A ; - 02B0 18 08 592 JR GETPORTDISP ; - 02B2 593 GETPORTCLEAR: - 02B2 3E 12 594 LD A,#0x12 ; - 02B4 32r8Bs07 595 LD (DISPLAYBUF),A ; - 02B7 32r8Cs07 596 LD (DISPLAYBUF+1),A ; - 02BA 597 GETPORTDISP: - 02BA 3Ar8Bs07 598 LD A,(DISPLAYBUF) ; - 02BD CDrF8s06 599 CALL DECODEDISPLAY ; - 02C0 32rD7s0C 600 LD (PORT),A ; - 02C3 3Ar8Cs07 601 LD A,(DISPLAYBUF+1) ; - 02C6 CDrF8s06 602 CALL DECODEDISPLAY ; - 02C9 32rD8s0C 603 LD (PORT+1),A ; - 02CC C3r6Fs02 604 JP GETPORT1 ; - 605 - 606 - 607 ;__GETVALUE______________________________________________________________________________________________________________________ - 608 ; - 609 ; GET VALUE FROM FRONT PANEL - 610 ;________________________________________________________________________________________________________________________________ - 611 ; - 02CF 612 GETVALUE: - 02CF C5 613 PUSH BC ; STORE BC - 02D0 18 40 614 JR GETVALUECLEAR ; - 02D2 615 GETVALUE1: - 02D2 CDrBEs06 616 CALL HEXDISPLAY ; - 617 - 02D5 618 GETVALUELOOP: - 02D5 CDr40s06 619 CALL KB_GET ; - 02D8 FE 10 620 CP #0x10 ; - 02DA FAr05s03 621 JP M,GETVALUENUM ; NUMBER PRESSED, STORE IT - 02DD FE 13 622 CP #0x13 ; EN PRESSED, DONE - 02DF 28 06 623 JR Z,GETVALUEDONE ; - 02E1 FE 12 624 CP #0x12 ; CLEAR PRESSED, CLEAR - 02E3 28 2D 625 JR Z,GETVALUECLEAR ; - 02E5 18 EE 626 JR GETVALUELOOP ; INVALID KEY, LOOP - 02E7 627 GETVALUEDONE: - 02E7 3Ar8Cs07 628 LD A,(DISPLAYBUF+1) ; - 02EA CB 27 629 SLA A ; - 02EC CB 27 630 SLA A ; - 02EE CB 27 631 SLA A ; - 02F0 CB 27 632 SLA A ; - 02F2 4F 633 LD C,A ; - 02F3 3Ar8Bs07 634 LD A,(DISPLAYBUF) ; - 02F6 E6 0F 635 AND #0x0F ; - 02F8 B1 636 OR C ; - 02F9 4F 637 LD C,A ; - 02FA 3E 10 638 LD A,#0x10 ; - 02FC 32r8Bs07 639 LD (DISPLAYBUF),A ; - 02FF 32r8Cs07 640 LD (DISPLAYBUF+1),A ; - 0302 79 641 LD A,C ; - 0303 C1 642 POP BC ; RESTORE BC - 0304 C9 643 RET - 0305 644 GETVALUENUM: - 0305 4F 645 LD C,A ; - 0306 3Ar8Bs07 646 LD A,(DISPLAYBUF) ; - 0309 32r8Cs07 647 LD (DISPLAYBUF+1),A ; - 030C 79 648 LD A,C ; - 030D 32r8Bs07 649 LD (DISPLAYBUF+0),A ; - 0310 18 C0 650 JR GETVALUE1 ; - 0312 651 GETVALUECLEAR: - 0312 3E 12 652 LD A,#0x12 ; - 0314 32r8Bs07 653 LD (DISPLAYBUF),A ; - 0317 32r8Cs07 654 LD (DISPLAYBUF+1),A ; - 031A C3rD2s02 655 JP GETVALUE1 ; - 656 - 657 - 658 ;__MONSTARTWARM___________________________________________________________________________________________________________________ - 659 ; - 660 ; SERIAL MONITOR STARTUP - 661 ;________________________________________________________________________________________________________________________________ - 662 ; - 663 - 031D 664 MONSTARTWARM: ; CALL HERE FOR SERIAL MONITOR WARM START - 031D 31 FF CF 665 LD SP,#STACKSTART ; SET THE STACK POINTER TO STACKSTART - 0320 CDr32s06 666 CALL INITIALIZE ; INITIALIZE SYSTEM - 667 - 0323 AF 668 XOR A ;ZERO OUT ACCUMULATOR (ADDED) - 0324 E5 669 PUSH HL ;PROTECT HL FROM OVERWRITE - 0325 21r9Bs09 670 LD HL,#TXT_READY ;POINT AT TEXT - 0328 CDr8As04 671 CALL MSG ;SHOW WE'RE HERE - 032B E1 672 POP HL ;PROTECT HL FROM OVERWRITE - 673 - 674 ; - 675 ;__SERIAL_MONITOR_COMMANDS_________________________________________________________________________________________________________ - 676 ; - 677 ; B XX BOOT CPM FROM DRIVE XX - 678 ; D XXXXH YYYYH DUMP MEMORY FROM XXXX TO YYYY - 679 ; F XXXXH YYYYH ZZH FILL MEMORY FROM XXXX TO YYYY WITH ZZ - 680 ; H LOAD INTEL HEX FORMAT DATA - 681 ; I INPUT FROM PORT AND SHOW HEX DATA - 682 ; K ECHO KEYBOARD INPUT - 683 ; M XXXXH YYYYH ZZZZH MOVE MEMORY BLOCK XXXX TO YYYY TO ZZZZ - 684 ; O OUTPUT TO PORT HEX DATA - 685 ; P XXXXH YYH PROGRAM RAM FROM XXXXH WITH VALUE IN YYH, WILL PROMPT FOR NEXT LINES FOLLOWING UNTIL CR - 686 ; R RUN A PROGRAM FROM CURRENT LOCATION - 687 - 688 - 689 - 690 ;__COMMAND_PARSE_________________________________________________________________________________________________________________ - 691 ; - 692 ; PROMPT USER FOR COMMANDS, THEN PARSE THEM - 693 ;________________________________________________________________________________________________________________________________ - 694 ; - 695 - 032C 696 SERIALCMDLOOP: - 032C CDr81s04 697 CALL CRLFA ; CR,LF,> - 032F 21r3Bs07 698 LD HL,#KEYBUF ; SET POINTER TO KEYBUF AREA - 0332 CDr81s03 699 CALL GETLN ; GET A LINE OF INPUT FROM THE USER - 0335 21r3Bs07 700 LD HL,#KEYBUF ; RESET POINTER TO START OF KEYBUF - 0338 7E 701 LD A,(HL) ; LOAD FIRST CHAR INTO A (THIS SHOULD BE THE COMMAND) - 0339 23 702 INC HL ; INC POINTER - 703 - 033A FE 42 704 CP #ASCIIB ; IS IT "B" (Y/N) - 033C CAr33s00 705 JP Z,DOBOOT ; IF YES DO BOOT - 033F FE 52 706 CP #ASCIIR ; IS IT "R" (Y/N) - 0341 CAr98s04 707 JP Z,RUN ; IF YES GO RUN ROUTINE - 0344 FE 50 708 CP #ASCIIP ; IS IT "P" (Y/N) - 0346 CAr9Ds04 709 JP Z,PROGRM ; IF YES GO PROGRAM ROUTINE - 0349 FE 4F 710 CP #ASCIIO ; IS IT AN "O" (Y/N) - 034B CAr63s04 711 JP Z,POUT ; PORT OUTPUT - 034E FE 48 712 CP #ASCIIH ; IS IT A "H" (Y/N) - 0350 CAr30s05 713 JP Z,HXLOAD ; INTEL HEX FORMAT LOAD DATA - 0353 FE 49 714 CP #ASCIII ; IS IT AN "I" (Y/N) - 0355 CAr71s04 715 JP Z,PIN ; PORT INPUT - 0358 FE 44 716 CP #ASCIID ; IS IT A "D" (Y/N) - 035A CArD4s04 717 JP Z,DUMP ; DUMP MEMORY - 035D FE 4B 718 CP #ASCIIK - 035F CAr74s03 719 JP Z,KLOP ; LOOP ON KEYBOARD - 0362 FE 4D 720 CP #ASCIIM ; IS IT A "M" (Y/N) - 0364 CAr9Cs05 721 JP Z,MOVE ; MOVE MEMORY COMMAND - 0367 FE 46 722 CP #ASCIIF ; IS IT A "F" (Y/N) - 0369 CArDDs05 723 JP Z,FILL ; FILL MEMORY COMMAND - 036C 21rA2s0C 724 LD HL,#TXT_COMMAND ; POINT AT ERROR TEXT - 036F CDr8As04 725 CALL MSG ; PRINT COMMAND LABEL - 726 - 0372 18 B8 727 JR SERIALCMDLOOP - 728 - 729 - 730 - 731 - 732 - 733 ;__KLOP__________________________________________________________________________________________________________________________ - 734 ; - 735 ; READ FROM THE SERIAL PORT AND ECHO, MONITOR COMMAND "K" - 736 ;________________________________________________________________________________________________________________________________ - 737 ; - 0374 738 KLOP: - 0374 CDrB4s03 739 CALL KIN ; GET A KEY - 0377 CDrC8s03 740 CALL COUT ; OUTPUT KEY TO SCREEN - 037A FE 1B 741 CP #ESC ; IS ? - 037C 20 F6 742 JR NZ,KLOP ; NO, LOOP - 037E C3r2Cs03 743 JP SERIALCMDLOOP ; - 744 - 745 ;__GETLN_________________________________________________________________________________________________________________________ - 746 ; - 747 ; READ A LINE(80) OF TEXT FROM THE SERIAL PORT, HANDLE , TERM ON - 748 ; EXIT IF TOO MANY CHARS STORE RESULT IN HL. CHAR COUNT IN C. - 749 ;________________________________________________________________________________________________________________________________ - 750 ; - 0381 751 GETLN: - 0381 0E 00 752 LD C,#0 ; ZERO CHAR COUNTER - 0383 D5 753 PUSH DE ; STORE DE - 0384 754 GETLNLOP: - 0384 CDrB4s03 755 CALL KIN ; GET A KEY - 0387 CDrC8s03 756 CALL COUT ; OUTPUT KEY TO SCREEN - 038A FE 0D 757 CP #CR ; IS ? - 038C 28 22 758 JR Z,GETLNDONE ; YES, EXIT - 038E FE 08 759 CP #BS ; IS ? - 0390 20 16 760 JR NZ,GETLNSTORE ; NO, STORE CHAR - 0392 79 761 LD A,C ; A=C - 0393 FE 00 762 CP #0 ; - 0395 28 ED 763 JR Z,GETLNLOP ; NOTHING TO BACKSPACE, IGNORE & GET NEXT KEY - 0397 2B 764 DEC HL ; PERFORM BACKSPACE - 0398 0D 765 DEC C ; LOWER CHAR COUNTER - 0399 3E 00 766 LD A,#0 ; - 039B 77 767 LD (HL),A ; STORE NULL IN BUFFER - 039C 3E 20 768 LD A,#0x20 ; BLANK OUT CHAR ON TERM - 039E CDrC8s03 769 CALL COUT ; - 03A1 3E 08 770 LD A,#BS ; - 03A3 CDrC8s03 771 CALL COUT ; - 03A6 18 DC 772 JR GETLNLOP ; GET NEXT KEY - 03A8 773 GETLNSTORE: - 03A8 77 774 LD (HL),A ; STORE CHAR IN BUFFER - 03A9 23 775 INC HL ; INC POINTER - 03AA 0C 776 INC C ; INC CHAR COUNTER - 03AB 79 777 LD A,C ; A=C - 03AC FE 4D 778 CP #0x4D ; OUT OF BUFFER SPACE? - 03AE 20 D4 779 JR NZ,GETLNLOP ; NOPE, GET NEXT CHAR - 03B0 780 GETLNDONE: - 03B0 36 00 781 LD (HL),#0 ; STORE NULL IN BUFFER - 03B2 D1 782 POP DE ; RESTORE DE - 03B3 C9 783 RET ; - 784 - 785 - 786 ;__KIN___________________________________________________________________________________________________________________________ - 787 ; - 788 ; READ FROM THE SERIAL PORT AND ECHO & CONVERT INPUT TO UCASE - 789 ;________________________________________________________________________________________________________________________________ - 790 ; - 03B4 791 KIN: - 03B4 DB 6D 792 IN A,(UART5) ; READ LINE STATUS REGISTER - 03B6 CB 47 793 BIT 0,A ; TEST IF DATA IN RECEIVE BUFFER - 03B8 CArB4s03 794 JP Z,KIN ; LOOP UNTIL DATA IS READY - 03BB DB 68 795 IN A,(UART0) ; THEN READ THE CHAR FROM THE UART - 03BD E6 7F 796 AND #0x7F ; STRIP HI BIT - 03BF FE 41 797 CP #ASCIIA ; KEEP NUMBERS, CONTROLS - 03C1 D8 798 RET C ; AND UPPER CASE - 03C2 FE 7B 799 CP #0x7B ; SEE IF NOT LOWER CASE - 03C4 D0 800 RET NC ; - 03C5 E6 5F 801 AND #0x5F ; MAKE UPPER CASE - 03C7 C9 802 RET - 803 - 804 - 805 ;__COUT__________________________________________________________________________________________________________________________ - 806 ; - 807 ; WRITE THE VALUE IN "A" TO THE SERIAL PORT - 808 ;________________________________________________________________________________________________________________________________ - 809 ; - 03C8 810 COUT: - 03C8 F5 811 PUSH AF ; STORE AF - 03C9 812 TX_BUSYLP: - 03C9 DB 6D 813 IN A,(UART5) ; READ LINE STATUS REGISTER - 03CB CB 6F 814 BIT 5,A ; TEST IF UART IS READY TO SEND - 03CD CArC9s03 815 JP Z,TX_BUSYLP ; IF NOT REPEAT - 03D0 F1 816 POP AF ; RESTORE AF - 03D1 D3 68 817 OUT (UART0),A ; THEN WRITE THE CHAR TO UART - 03D3 C9 818 RET ; DONE - 819 - 820 - 821 ;__CRLF__________________________________________________________________________________________________________________________ - 822 ; - 823 ; SEND CR & LF TO THE SERIAL PORT - 824 ;________________________________________________________________________________________________________________________________ - 825 ; - 03D4 826 CRLF: - 03D4 E5 827 PUSH HL ; PROTECT HL FROM OVERWRITE - 03D5 21r94s09 828 LD HL,#TCRLF ; LOAD MESSAGE POINTER - 03D8 CDr8As04 829 CALL MSG ; SEBD MESSAGE TO SERIAL PORT - 03DB E1 830 POP HL ; PROTECT HL FROM OVERWRITE - 03DC C9 831 RET ; - 832 - 833 - 834 ;__LDHL__________________________________________________________________________________________________________________________ - 835 ; - 836 ; GET ONE WORD OF HEX DATA FROM BUFFER POINTED TO BY HL SERIAL PORT, RETURN IN HL - 837 ;________________________________________________________________________________________________________________________________ - 838 ; - 03DD 839 LDHL: - 03DD D5 840 PUSH DE ; STORE DE - 03DE CDrE9s03 841 CALL HEXIN ; GET K B. AND MAKE HEX - 03E1 57 842 LD D,A ; THATS THE HI BYTE - 03E2 CDrE9s03 843 CALL HEXIN ; DO HEX AGAIN - 03E5 6F 844 LD L,A ; THATS THE LOW BYTE - 03E6 62 845 LD H,D ; MOVE TO HL - 03E7 D1 846 POP DE ; RESTORE BC - 03E8 C9 847 RET ; GO BACK WITH ADDRESS - 848 - 849 - 850 ;__HEXIN__________________________________________________________________________________________________________________________ - 851 ; - 852 ; GET ONE BYTE OF HEX DATA FROM BUFFER IN HL, RETURN IN A - 853 ;________________________________________________________________________________________________________________________________ - 854 ; - 03E9 855 HEXIN: - 03E9 C5 856 PUSH BC ;SAVE BC REGS - 03EA CDrFCs03 857 CALL NIBL ;DO A NIBBLE - 03ED CB 07 858 RLC A ;MOVE FIRST BYTE UPPER NIBBLE - 03EF CB 07 859 RLC A ; - 03F1 CB 07 860 RLC A ; - 03F3 CB 07 861 RLC A ; - 03F5 47 862 LD B,A ; SAVE ROTATED BYTE - 03F6 CDrFCs03 863 CALL NIBL ; DO NEXT NIBBLE - 03F9 80 864 ADD A,B ; COMBINE NIBBLES IN ACC - 03FA C1 865 POP BC ; RESTORE BC - 03FB C9 866 RET ; DONE - 03FC 867 NIBL: - 03FC 7E 868 LD A,(HL) ; GET K B. DATA - 03FD 23 869 INC HL ; INC KB POINTER - 03FE FE 40 870 CP #0x40 ; TEST FOR ALPHA - 0400 30 03 871 JR NC,ALPH ; - 0402 E6 0F 872 AND #0x0F ; GET THE BITS - 0404 C9 873 RET ; - 0405 874 ALPH: - 0405 E6 0F 875 AND #0x0F ; GET THE BITS - 0407 C6 09 876 ADD A,#9 ; MAKE IT HEX A-F - 0409 C9 877 RET ; - 878 - 879 - 880 ;__HEXINS_________________________________________________________________________________________________________________________ - 881 ; - 882 ; GET ONE BYTE OF HEX DATA FROM SERIAL PORT, RETURN IN A - 883 ;________________________________________________________________________________________________________________________________ - 884 ; - 040A 885 HEXINS: - 040A C5 886 PUSH BC ;SAVE BC REGS - 040B CDr1Ds04 887 CALL NIBLS ;DO A NIBBLE - 040E CB 07 888 RLC A ;MOVE FIRST BYTE UPPER NIBBLE - 0410 CB 07 889 RLC A ; - 0412 CB 07 890 RLC A ; - 0414 CB 07 891 RLC A ; - 0416 47 892 LD B,A ; SAVE ROTATED BYTE - 0417 CDr1Ds04 893 CALL NIBLS ; DO NEXT NIBBLE - 041A 80 894 ADD A,B ; COMBINE NIBBLES IN ACC - 041B C1 895 POP BC ; RESTORE BC - 041C C9 896 RET ; DONE - 041D 897 NIBLS: - 041D CDrB4s03 898 CALL KIN ; GET K B. DATA - 0420 23 899 INC HL ; INC KB POINTER - 0421 FE 40 900 CP #0x40 ; TEST FOR ALPHA - 0423 30 E0 901 JR NC,ALPH ; - 0425 E6 0F 902 AND #0x0F ; GET THE BITS - 0427 C9 903 RET ; - 904 - 905 - 906 ;__HXOUT_________________________________________________________________________________________________________________________ - 907 ; - 908 ; PRINT THE ACCUMULATOR CONTENTS AS HEX DATA ON THE SERIAL PORT - 909 ;________________________________________________________________________________________________________________________________ - 910 ; - 0428 911 HXOUT: - 0428 C5 912 PUSH BC ; SAVE BC - 0429 47 913 LD B,A ; - 042A CB 07 914 RLC A ; DO HIGH NIBBLE FIRST - 042C CB 07 915 RLC A ; - 042E CB 07 916 RLC A ; - 0430 CB 07 917 RLC A ; - 0432 E6 0F 918 AND #0x0F ; ONLY THIS NOW - 0434 C6 30 919 ADD A,#0x30 ; TRY A NUMBER - 0436 FE 3A 920 CP #0x3A ; TEST IT - 0438 38 02 921 JR C,OUT1 ; IF CY SET PRINT 'NUMBER' - 043A C6 07 922 ADD A,#0x07 ; MAKE IT AN ALPHA - 043C 923 OUT1: - 043C CDrC8s03 924 CALL COUT ; SCREEN IT - 043F 78 925 LD A,B ; NEXT NIBBLE - 0440 E6 0F 926 AND #0x0F ; JUST THIS - 0442 C6 30 927 ADD A,#0x30 ; TRY A NUMBER - 0444 FE 3A 928 CP #0x3A ; TEST IT - 0446 38 02 929 JR C,OUT2 ; PRINT 'NUMBER' - 0448 C6 07 930 ADD A,#7 ; MAKE IT ALPHA - 044A 931 OUT2: - 044A CDrC8s03 932 CALL COUT ; SCREEN IT - 044D C1 933 POP BC ; RESTORE BC - 044E C9 934 RET ; - 935 - 936 - 937 ;__SPACE_________________________________________________________________________________________________________________________ - 938 ; - 939 ; PRINT A SPACE CHARACTER ON THE SERIAL PORT - 940 ;________________________________________________________________________________________________________________________________ - 941 ; - 044F 942 SPACE: - 044F F5 943 PUSH AF ; STORE AF - 0450 3E 20 944 LD A,#0x20 ; LOAD A "SPACE" - 0452 CDrC8s03 945 CALL COUT ; SCREEN IT - 0455 F1 946 POP AF ; RESTORE AF - 0456 C9 947 RET ; DONE - 948 - 949 ;__PHL_________________________________________________________________________________________________________________________ - 950 ; - 951 ; PRINT THE HL REG ON THE SERIAL PORT - 952 ;________________________________________________________________________________________________________________________________ - 953 ; - 0457 954 PHL: - 0457 7C 955 LD A,H ; GET HI BYTE - 0458 CDr28s04 956 CALL HXOUT ; DO HEX OUT ROUTINE - 045B 7D 957 LD A,L ; GET LOW BYTE - 045C CDr28s04 958 CALL HXOUT ; HEX IT - 045F CDr4Fs04 959 CALL SPACE ; - 0462 C9 960 RET ; DONE - 961 - 962 ;__POUT__________________________________________________________________________________________________________________________ - 963 ; - 964 ; OUTPUT TO AN I/O PORT, MONITOR COMMAND "O" - 965 ;________________________________________________________________________________________________________________________________ - 966 ; - 0463 967 POUT: - 0463 968 POUT1: - 0463 23 969 INC HL ; - 0464 CDrE9s03 970 CALL HEXIN ; GET PORT - 0467 4F 971 LD C,A ; SAVE PORT POINTER - 0468 23 972 INC HL ; - 0469 CDrE9s03 973 CALL HEXIN ; GET DATA - 046C 974 OUTIT: - 046C ED 79 975 OUT (C),A ; - 046E C3r2Cs03 976 JP SERIALCMDLOOP ; - 977 - 978 - 979 ;__PIN___________________________________________________________________________________________________________________________ - 980 ; - 981 ; INPUT FROM AN I/O PORT, MONITOR COMMAND "I" - 982 ;________________________________________________________________________________________________________________________________ - 983 ; - 0471 984 PIN: - 0471 23 985 INC HL ; - 0472 CDrE9s03 986 CALL HEXIN ; GET PORT - 0475 4F 987 LD C,A ; SAVE PORT POINTER - 0476 CDrD4s03 988 CALL CRLF ; - 0479 ED 78 989 IN A,(C) ; GET DATA - 047B CDr28s04 990 CALL HXOUT ; SHOW IT - 047E C3r2Cs03 991 JP SERIALCMDLOOP ; - 992 - 993 - 994 - 995 - 996 - 997 ;__CRLFA_________________________________________________________________________________________________________________________ - 998 ; - 999 ; PRINT COMMAND PROMPT TO THE SERIAL PORT - 1000 ;________________________________________________________________________________________________________________________________ - 1001 ; - 0481 1002 CRLFA: - 0481 E5 1003 PUSH HL ; PROTECT HL FROM OVERWRITE - 0482 21r97s09 1004 LD HL,#PROMPT ; - 0485 CDr8As04 1005 CALL MSG ; - 0488 E1 1006 POP HL ; PROTECT HL FROM OVERWRITE - 0489 C9 1007 RET ; DONE - 1008 - 1009 - 1010 ;__MSG___________________________________________________________________________________________________________________________ - 1011 ; - 1012 ; PRINT A STRING TO THE SERIAL PORT - 1013 ;________________________________________________________________________________________________________________________________ - 1014 ; - 048A 1015 MSG: - 1016 - 048A 1017 TX_SERLP: - 048A 7E 1018 LD A,(HL) ; GET CHARACTER TO A - 048B FE FF 1019 CP #ENDT ; TEST FOR END BYTE - 048D CAr97s04 1020 JP Z,TX_END ; JUMP IF END BYTE IS FOUND - 0490 CDrC8s03 1021 CALL COUT ; - 0493 23 1022 INC HL ; INC POINTER, TO NEXT CHAR - 0494 C3r8As04 1023 JP TX_SERLP ; TRANSMIT LOOP - 0497 1024 TX_END: - 0497 C9 1025 RET ;ELSE DONE - 1026 - 1027 ;__RUN___________________________________________________________________________________________________________________________ - 1028 ; - 1029 ; TRANSFER OUT OF MONITOR, USER OPTION "R" - 1030 ;________________________________________________________________________________________________________________________________ - 1031 ; - 0498 1032 RUN: - 0498 23 1033 INC HL ; SHOW READY - 0499 CDrDDs03 1034 CALL LDHL ; GET START ADDRESS - 049C E9 1035 JP (HL) ; - 1036 - 1037 - 1038 ;__PROGRM________________________________________________________________________________________________________________________ - 1039 ; - 1040 ; PROGRAM RAM LOCATIONS, USER OPTION "P" - 1041 ;________________________________________________________________________________________________________________________________ - 1042 ; - 049D 1043 PROGRM: - 049D 23 1044 INC HL ; SHOW READY - 049E E5 1045 PUSH HL ; STORE HL - 049F CDrDDs03 1046 CALL LDHL ; GET START ADDRESS - 04A2 54 1047 LD D,H ; - 04A3 5D 1048 LD E,L ; DE POINTS TO ADDRESS TO PROGRAM - 04A4 E1 1049 POP HL ; - 04A5 23 1050 INC HL ; - 04A6 23 1051 INC HL ; - 04A7 23 1052 INC HL ; - 04A8 23 1053 INC HL ; - 04A9 23 1054 INC HL ; - 04AA 1055 PROGRMLP: - 04AA CDrE9s03 1056 CALL HEXIN ; GET NEXT HEX NUMBER - 04AD 12 1057 LD (DE),A ; STORE IT - 04AE 13 1058 INC DE ; NEXT ADDRESS; - 04AF CDr81s04 1059 CALL CRLFA ; CR,LF,> - 04B2 3E 50 1060 LD A,#ASCIIP ; - 04B4 CDrC8s03 1061 CALL COUT ; - 04B7 CDr4Fs04 1062 CALL SPACE ; - 04BA 62 1063 LD H,D ; - 04BB 6B 1064 LD L,E ; - 04BC CDr57s04 1065 CALL PHL ; - 04BF 21r3Bs07 1066 LD HL,#KEYBUF ; SET POINTER TO KEYBUF AREA - 04C2 CDr81s03 1067 CALL GETLN ; GET A LINE OF INPUT FROM THE USER - 04C5 21r3Bs07 1068 LD HL,#KEYBUF ; RESET POINTER TO START OF KEYBUF - 04C8 7E 1069 LD A,(HL) ; LOAD FIRST CHAR INTO A - 04C9 FE 00 1070 CP #0 ; END OF LINE? - 04CB CArD1s04 1071 JP Z,PROGRMEXIT ; YES, EXIT - 04CE C3rAAs04 1072 JP PROGRMLP ; NO, LOOP - 04D1 1073 PROGRMEXIT: - 04D1 C3r2Cs03 1074 JP SERIALCMDLOOP - 1075 - 1076 - 1077 - 1078 - 1079 - 1080 - 1081 - 1082 ;__DUMP__________________________________________________________________________________________________________________________ - 1083 ; - 1084 ; PRINT A MEMORY DUMP, USER OPTION "D" - 1085 ;________________________________________________________________________________________________________________________________ - 1086 ; - 04D4 1087 DUMP: - 04D4 23 1088 INC HL ; SHOW READY - 04D5 E5 1089 PUSH HL ; STORE HL - 04D6 CDrDDs03 1090 CALL LDHL ; GET START ADDRESS - 04D9 54 1091 LD D,H ; - 04DA 5D 1092 LD E,L ; - 04DB E1 1093 POP HL ; - 04DC D5 1094 PUSH DE ; SAVE START - 04DD 23 1095 INC HL ; - 04DE 23 1096 INC HL ; - 04DF 23 1097 INC HL ; - 04E0 23 1098 INC HL ; - 04E1 23 1099 INC HL ; - 04E2 CDrDDs03 1100 CALL LDHL ; GET END ADDRESS - 04E5 23 1101 INC HL ; ADD ONE MORE FOR LATER COMPARE - 04E6 EB 1102 EX DE,HL ; PUT END ADDRESS IN DE - 04E7 E1 1103 POP HL ; GET BACK START - 04E8 1104 GDATA: - 04E8 CDrD4s03 1105 CALL CRLF ; - 04EB 1106 BLKRD: - 04EB CDr57s04 1107 CALL PHL ; PRINT START LOCATION - 04EE 0E 10 1108 LD C,#16 ; SET FOR 16 LOCS - 04F0 E5 1109 PUSH HL ; SAVE STARTING HL - 04F1 1110 NXTONE: - 04F1 D9 1111 EXX ; - 04F2 4B 1112 LD C,E ; - 04F3 ED 78 1113 IN A,(C) ; - 04F5 D9 1114 EXX ; - 04F6 E6 7F 1115 AND #0x7F ; - 04F8 FE 1B 1116 CP #ESC ; - 04FA CAr2Cs03 1117 JP Z,SERIALCMDLOOP ; - 04FD FE 13 1118 CP #19 ; - 04FF 28 F0 1119 JR Z,NXTONE ; - 0501 7E 1120 LD A,(HL) ; GET BYTE - 0502 CDr28s04 1121 CALL HXOUT ; PRINT IT - 0505 CDr4Fs04 1122 CALL SPACE ; - 0508 1123 UPDH: - 0508 23 1124 INC HL ; POINT NEXT - 0509 0D 1125 DEC C ; DEC LOC COUNT - 050A 20 E5 1126 JR NZ,NXTONE ; IF LINE NOT DONE - 1127 ; NOW PRINT 'DECODED' DATA TO RIGHT OF DUMP - 050C 1128 PCRLF: - 050C CDr4Fs04 1129 CALL SPACE ; SPACE IT - 050F 0E 10 1130 LD C,#16 ; SET FOR 16 CHARS - 0511 E1 1131 POP HL ; GET BACK START - 0512 1132 PCRLF0: - 0512 7E 1133 LD A,(HL) ; GET BYTE - 0513 E6 60 1134 AND #0x060 ; SEE IF A 'DOT' - 0515 7E 1135 LD A,(HL) ; O K. TO GET - 0516 20 02 1136 JR NZ,PDOT ; - 0518 1137 DOT: - 0518 3E 2E 1138 LD A,#0x2E ; LOAD A DOT - 051A 1139 PDOT: - 051A CDrC8s03 1140 CALL COUT ; PRINT IT - 051D 23 1141 INC HL ; - 051E 7A 1142 LD A,D ; - 051F BC 1143 CP H ; - 0520 20 05 1144 JR NZ,UPDH1 ; - 0522 7B 1145 LD A,E ; - 0523 BD 1146 CP L ; - 0524 CAr2Cs03 1147 JP Z,SERIALCMDLOOP ; - 1148 ; - 1149 ;IF BLOCK NOT DUMPED, DO NEXT CHARACTER OR LINE - 0527 1150 UPDH1: - 0527 0D 1151 DEC C ; DEC CHAR COUNT - 0528 20 E8 1152 JR NZ,PCRLF0 ; DO NEXT - 052A 1153 CONTD: - 052A CDrD4s03 1154 CALL CRLF ; - 052D C3rEBs04 1155 JP BLKRD ; - 1156 - 1157 - 1158 ;__HXLOAD__________________________________________________________________________________________________________________________ - 1159 ; - 1160 ; LOAD INTEL HEX FORMAT FILE FROM THE SERIAL PORT, USER OPTION "H" - 1161 ; - 1162 ; [INTEL HEX FORMAT IS: - 1163 ; 1) COLON (FRAME 0) - 1164 ; 2) RECORD LENGTH FIELD (FRAMES 1 AND 2) - 1165 ; 3) LOAD ADDRESS FIELD (FRAMES 3,4,5,6) - 1166 ; 4) RECORD TYPE FIELD (FRAMES 7 AND 8) - 1167 ; 5) DATA FIELD (FRAMES 9 TO 9+2*(RECORD LENGTH)-1 - 1168 ; 6) CHECKSUM FIELD - SUM OF ALL BYTE VALUES FROM RECORD LENGTH TO AND - 1169 ; INCLUDING CHECKSUM FIELD = 0 ] - 1170 ; - 1171 ; EXAMPLE OF INTEL HEX FORMAT FILE - 1172 ; EACH LINE CONTAINS A CARRIAGE RETURN AS THE LAST CHARACTER - 1173 ; :18F900002048454C4C4F20574F524C4420FF0D0AFF0D0A3EFF0D0A54BF - 1174 ; :18F918006573742050726F746F7479706520524F4D204D6F6E69746FF1 - 1175 ; :18F9300072205265616479200D0AFF0D0A434F4D4D414E4420524543F2 - 1176 ; :18F948004549564544203AFF0D0A434845434B53554D204552524F52CD - 1177 ; :16F96000FF0A0D20202D454E442D4F462D46494C452D20200A0DA4 - 1178 ; :00000001FF - 1179 ;________________________________________________________________________________________________________________________________ - 0530 1180 HXLOAD: - 0530 CDrD4s03 1181 CALL CRLF ; SHOW READY - 0533 1182 HXLOAD0: - 0533 CDrB4s03 1183 CALL KIN ; GET THE FIRST CHARACTER, EXPECTING A ':' - 0536 1184 HXLOAD1: - 0536 FE 3A 1185 CP #0x3A ; IS IT COLON ':'? START OF LINE OF INTEL HEX FILE - 0538 20 47 1186 JR NZ,HXLOADERR ; IF NOT, MUST BE ERROR, ABORT ROUTINE - 053A 1E 00 1187 LD E,#0 ; FIRST TWO CHARACTERS IS THE RECORD LENGTH FIELD - 053C CDr0As04 1188 CALL HEXINS ; GET US TWO CHARACTERS INTO BC, CONVERT IT TO A BYTE - 053F CDr8As05 1189 CALL HXCHKSUM ; UPDATE HEX CHECK SUM - 0542 57 1190 LD D,A ; LOAD RECORD LENGTH COUNT INTO D - 0543 CDr0As04 1191 CALL HEXINS ; GET NEXT TWO CHARACTERS, MEMORY LOAD ADDRESS - 0546 CDr8As05 1192 CALL HXCHKSUM ; UPDATE HEX CHECK SUM - 0549 67 1193 LD H,A ; PUT VALUE IN H REGISTER - 054A CDr0As04 1194 CALL HEXINS ; GET NEXT TWO CHARACTERS, MEMORY LOAD ADDRESS - 054D CDr8As05 1195 CALL HXCHKSUM ; UPDATE HEX CHECK SUM - 0550 6F 1196 LD L,A ; PUT VALUE IN L REGISTER - 0551 CDr0As04 1197 CALL HEXINS ; GET NEXT TWO CHARACTERS, RECORD FIELD TYPE - 0554 CDr8As05 1198 CALL HXCHKSUM ; UPDATE HEX CHECK SUM - 0557 FE 01 1199 CP #1 ; RECORD FIELD TYPE 00 IS DATA, 01 IS END OF FILE - 0559 20 0D 1200 JR NZ,HXLOAD2 ; MUST BE THE END OF THAT FILE - 055B CDr0As04 1201 CALL HEXINS ; GET NEXT TWO CHARACTERS, ASSEMBLE INTO BYTE - 055E CDr8As05 1202 CALL HXCHKSUM ; UPDATE HEX CHECK SUM - 0561 7B 1203 LD A,E ; RECALL THE CHECKSUM BYTE - 0562 A7 1204 AND A ; IS IT ZERO? - 0563 CAr96s05 1205 JP Z,HXLOADEXIT ; MUST BE O K., GO BACK FOR SOME MORE, ELSE - 0566 18 19 1206 JR HXLOADERR ; CHECKSUMS DON'T ADD UP, ERROR OUT - 0568 1207 HXLOAD2: - 0568 7A 1208 LD A,D ; RETRIEVE LINE CHARACTER COUNTER - 0569 A7 1209 AND A ; ARE WE DONE WITH THIS LINE? - 056A 28 0B 1210 JR Z,HXLOAD3 ; GET TWO MORE ASCII CHARACTERS, BUILD A BYTE AND CHECKSUM - 056C CDr0As04 1211 CALL HEXINS ; GET NEXT TWO CHARS, CONVERT TO BYTE IN A, CHECKSUM IT - 056F CDr8As05 1212 CALL HXCHKSUM ; UPDATE HEX CHECK SUM - 0572 77 1213 LD (HL),A ; CHECKSUM OK, MOVE CONVERTED BYTE IN A TO MEMORY LOCATION - 0573 23 1214 INC HL ; INCREMENT POINTER TO NEXT MEMORY LOCATION - 0574 15 1215 DEC D ; DECREMENT LINE CHARACTER COUNTER - 0575 18 F1 1216 JR HXLOAD2 ; AND KEEP LOADING INTO MEMORY UNTIL LINE IS COMPLETE - 0577 1217 HXLOAD3: - 0577 CDr0As04 1218 CALL HEXINS ; GET TWO CHARS, BUILD BYTE AND CHECKSUM - 057A CDr8As05 1219 CALL HXCHKSUM ; UPDATE HEX CHECK SUM - 057D 7B 1220 LD A,E ; CHECK THE CHECKSUM VALUE - 057E A7 1221 AND A ; IS IT ZERO? - 057F 28 0F 1222 JR Z,HXLOADAGAIN ; IF THE CHECKSUM IS STILL OK, CONTINUE ON, ELSE - 0581 1223 HXLOADERR: - 0581 21rB5s0C 1224 LD HL,#TXT_CKSUMERR ; GET "CHECKSUM ERROR" MESSAGE - 0584 CDr8As04 1225 CALL MSG ; PRINT MESSAGE FROM (HL) AND TERMINATE THE LOAD - 0587 C3r96s05 1226 JP HXLOADEXIT ; RETURN TO PROMPT - 058A 1227 HXCHKSUM: - 058A 4F 1228 LD C,A ; BUILD THE CHECKSUM - 058B 7B 1229 LD A,E ; - 058C 91 1230 SUB C ; THE CHECKSUM SHOULD ALWAYS .EQUAL ZERO WHEN CHECKED - 058D 5F 1231 LD E,A ; SAVE THE CHECKSUM BACK WHERE IT CAME FROM - 058E 79 1232 LD A,C ; RETRIEVE THE BYTE AND GO BACK - 058F C9 1233 RET ; BACK TO CALLER - 0590 1234 HXLOADAGAIN: - 0590 CDrB4s03 1235 CALL KIN ; CATCH THE TRAILING CARRIAGE RETURN - 0593 C3r33s05 1236 JP HXLOAD0 ; LOAD ANOTHER LINE OF DATA - 0596 1237 HXLOADEXIT: - 0596 CDrB4s03 1238 CALL KIN ; CATCH ANY STRAY TRAILING CHARACTERS - 0599 C3r2Cs03 1239 JP SERIALCMDLOOP ; RETURN TO PROMPT - 1240 - 1241 - 1242 ;__MOVE__________________________________________________________________________________________________________________________ - 1243 ; - 1244 ; MOVE MEMORY, USER OPTION "M" - 1245 ;________________________________________________________________________________________________________________________________ - 1246 ; - 059C 1247 MOVE: - 059C 0E 03 1248 LD C,#3 - 1249 ; START GETNM REPLACEMENT - 1250 ; GET SOURCE STARTING MEMORY LOCATION - 059E 23 1251 INC HL ; SHOW EXAMINE READY - 059F E5 1252 PUSH HL ; - 05A0 CDrDDs03 1253 CALL LDHL ; LOAD IN HL REGS - 05A3 54 1254 LD D,H ; - 05A4 5D 1255 LD E,L ; - 05A5 E1 1256 POP HL ; - 05A6 D5 1257 PUSH DE ; PUSH MEMORY ADDRESS ON STACK - 05A7 23 1258 INC HL ; - 05A8 23 1259 INC HL ; - 05A9 23 1260 INC HL ; - 05AA 23 1261 INC HL ; - 05AB 23 1262 INC HL ; PRINT SPACE SEPARATOR - 05AC E5 1263 PUSH HL ; - 05AD CDrDDs03 1264 CALL LDHL ; LOAD IN HL REGS - 05B0 54 1265 LD D,H ; - 05B1 5D 1266 LD E,L ; - 05B2 E1 1267 POP HL ; - 05B3 D5 1268 PUSH DE ; PUSH MEMORY ADDRESS ON STACK - 05B4 23 1269 INC HL ; - 05B5 23 1270 INC HL ; - 05B6 23 1271 INC HL ; - 05B7 23 1272 INC HL ; - 05B8 23 1273 INC HL ; PRINT SPACE SEPARATOR - 05B9 CDrDDs03 1274 CALL LDHL ; LOAD IN HL REGS - 05BC E5 1275 PUSH HL ; PUSH MEMORY ADDRESS ON STACK - 1276 ; END GETNM REPLACEMENT - 05BD D1 1277 POP DE ; DEST - 05BE C1 1278 POP BC ; SOURCE END - 05BF E1 1279 POP HL ; SOURCE - 05C0 E5 1280 PUSH HL ; - 05C1 7D 1281 LD A,L ; - 05C2 2F 1282 CPL ; - 05C3 6F 1283 LD L,A ; - 05C4 7C 1284 LD A,H ; - 05C5 2F 1285 CPL ; - 05C6 67 1286 LD H,A ; - 05C7 23 1287 INC HL ; - 05C8 09 1288 ADD HL,BC ; - 05C9 4D 1289 LD C,L ; - 05CA 44 1290 LD B,H ; - 05CB E1 1291 POP HL ; - 05CC CDrD2s05 1292 CALL MOVE_LOOP ; - 05CF C3r2Cs03 1293 JP SERIALCMDLOOP ; EXIT MOVE COMMAND ROUTINE - 05D2 1294 MOVE_LOOP: - 05D2 7E 1295 LD A,(HL) ; FETCH - 05D3 12 1296 LD (DE),A ; DEPOSIT - 05D4 23 1297 INC HL ; BUMP SOURCE - 05D5 13 1298 INC DE ; BUMP DEST - 05D6 0B 1299 DEC BC ; DEC COUNT - 05D7 79 1300 LD A,C ; - 05D8 B0 1301 OR B ; - 05D9 C2rD2s05 1302 JP NZ,MOVE_LOOP ; TIL COUNT=0 - 05DC C9 1303 RET ; - 1304 - 1305 ;__FILL__________________________________________________________________________________________________________________________ - 1306 ; - 1307 ; FILL MEMORY, USER OPTION "M" - 1308 ;________________________________________________________________________________________________________________________________ - 1309 ; - 05DD 1310 FILL: - 05DD 0E 03 1311 LD C,#3 ; - 1312 ; START GETNM REPLACEMENT - 1313 ; GET FILL STARTING MEMORY LOCATION - 05DF 23 1314 INC HL ; SHOW EXAMINE READY - 05E0 E5 1315 PUSH HL ; - 05E1 CDrDDs03 1316 CALL LDHL ; LOAD IN HL REGS - 05E4 54 1317 LD D,H ; - 05E5 5D 1318 LD E,L ; - 05E6 E1 1319 POP HL ; - 05E7 D5 1320 PUSH DE ; PUSH MEMORY ADDRESS ON STACK - 05E8 23 1321 INC HL ; - 05E9 23 1322 INC HL ; - 05EA 23 1323 INC HL ; - 05EB 23 1324 INC HL ; - 05EC 23 1325 INC HL ; PRINT SPACE SEPARATOR - 1326 ; GET FILL ENDING MEMORY LOCATION - 05ED E5 1327 PUSH HL ; - 05EE CDrDDs03 1328 CALL LDHL ; LOAD IN HL REGS - 05F1 54 1329 LD D,H ; - 05F2 5D 1330 LD E,L ; - 05F3 E1 1331 POP HL ; - 05F4 D5 1332 PUSH DE ; PUSH MEMORY ADDRESS ON STACK - 05F5 23 1333 INC HL ; - 05F6 23 1334 INC HL ; - 05F7 23 1335 INC HL ; - 05F8 23 1336 INC HL ; - 05F9 23 1337 INC HL ; PRINT SPACE SEPARATOR - 1338 ; GET TARGET STARTING MEMORY LOCATION - 05FA CDrE9s03 1339 CALL HEXIN ; GET K B. AND MAKE HEX - 05FD 4F 1340 LD C,A ; PUT FILL VALUE IN F SO IT IS SAVED FOR LATER - 05FE C5 1341 PUSH BC ; PUSH FILL VALUE BYTE ON STACK - 1342 ; END GETNM REPLACEMENT - 05FF C1 1343 POP BC ; BYTE - 0600 D1 1344 POP DE ; END - 0601 E1 1345 POP HL ; START - 0602 71 1346 LD (HL),C ; - 0603 1347 FILL_LOOP: - 0603 71 1348 LD (HL),C ; - 0604 23 1349 INC HL ; - 0605 7B 1350 LD A,E ; - 0606 95 1351 SUB L ; - 0607 47 1352 LD B,A ; - 0608 7A 1353 LD A,D ; - 0609 94 1354 SUB H ; - 060A B0 1355 OR B ; - 060B C2r03s06 1356 JP NZ,FILL_LOOP ; - 060E C3r2Cs03 1357 JP SERIALCMDLOOP ; - 1358 - 1359 ;__GOCPM_________________________________________________________________________________________________________________________ - 1360 ; - 1361 ; BOOT CP/M FROM ROM DRIVE, USER OPTION "C" - 1362 ;________________________________________________________________________________________________________________________________ - 1363 ; - 0611 1364 GOCPM: - 1365 ;___________________________ - 1366 ; REMOVE COMMENTS WHEN BURNED IN ROM - 1367 ;___________________________ - 1368 - 1369 ; LD A,000000000b ; RESET MPCL LATCH TO DEFAULT ROM - 1370 ; OUT (MPCL),A ; - 1371 ; LD HL,ROMSTART_CPM ; WHERE IN ROM CP/M IS STORED (FIRST BYTE) - 1372 ; LD DE,RAMTARG_CPM ; WHERE IN RAM TO MOVE MONITOR TO (FIRST BYTE) - 1373 ; LD BC,MOVSIZ_CPM ; NUMBER OF BYTES TO MOVE FROM ROM TO RAM - 1374 ; LDIR ; PERFORM BLOCK COPY OF CP/M TO UPPER RAM PAGE - 1375 ; LD A,010000000b ; RESET MPCL LATCH TO DEFAULT CP/M WITH 64K SETTING - 1376 ; OUT (MPCL),A ; - 1377 - 0611 C3 00 EA 1378 JP 0x0EA00 ; CP/M COLD BOOT ENTRY POINT - 1379 - 1380 ; - 1381 ;__INIT_UART_____________________________________________________________________________________________________________________ - 1382 ; - 1383 ; INITIALIZE UART - 1384 ; PARAMS: SER_BAUD NEEDS TO BE SET TO BAUD RATE - 1385 ; 1200: 96 = 1,843,200 / ( 16 X 1200 ) - 1386 ; 2400: 48 = 1,843,200 / ( 16 X 2400 ) - 1387 ; 4800: 24 = 1,843,200 / ( 16 X 4800 ) - 1388 ; 9600: 12 = 1,843,200 / ( 16 X 9600 ) - 1389 ; 19K2: 06 = 1,843,200 / ( 16 X 19,200 ) - 1390 ; 38K4: 03 - 1391 ; 57K6: 02 - 1392 ; 115K2: 01 - 1393 ; - 1394 ;_________________________________________________________________________________________________________________________________ - 1395 ; - 0614 1396 INIT_UART: - 0614 3E 80 1397 LD A,#0x80 ; - 0616 D3 6B 1398 OUT (UART3),A ; SET DLAB FLAG - 0618 3Ar3As07 1399 LD A,(SER_BAUD) ; - 061B D3 68 1400 OUT (UART0),A ; - 061D 3E 00 1401 LD A,#0 ; - 061F D3 69 1402 OUT (UART1),A ; - 0621 3E 03 1403 LD A,#3 ; - 0623 D3 6B 1404 OUT (UART3),A ; SET 8 BIT DATA, 1 STOPBIT - 0625 3E 03 1405 LD A,#3 ; set DTR & RTS - 0627 D3 6C 1406 OUT (UART4),A ; - 0629 C9 1407 RET - 1408 - 1409 - 1410 ; - 1411 ;__FILL_MEM_______________________________________________________________________________________________________________________ - 1412 ; - 1413 ; FUNCTION : FILL MEMORY WITH A VALUE - 1414 ; INPUT : HL = START ADDRESS BLOCK - 1415 ; : BC = LENGTH OF BLOCK - 1416 ; : A = VALUE TO FILL WITH - 1417 ; USES : DE, BC - 1418 ; OUTPUT : - 1419 ; CALLS : - 1420 ; TESTED : 13 FEB 2007 - 1421 ;_________________________________________________________________________________________________________________________________ - 1422 ; - 062A 1423 FILL_MEM: - 062A 5D 1424 LD E,L ; - 062B 54 1425 LD D,H ; - 062C 13 1426 INC DE ; - 062D 77 1427 LD (HL),A ; INITIALISE FIRST BYTE OF BLOCK WITH DATA BYTE IN A - 062E 0B 1428 DEC BC ; - 062F ED B0 1429 LDIR ; FILL MEMORY - 0631 C9 1430 RET ; RETURN TO CALLER - 1431 - 1432 ; - 1433 ;__INITIALIZE_____________________________________________________________________________________________________________________ - 1434 ; - 1435 ; INITIALIZE SYSTEM - 1436 ;_________________________________________________________________________________________________________________________________ - 1437 ; - 0632 1438 INITIALIZE: - 0632 3E 0C 1439 LD A,#12 ; SPECIFY BAUD RATE 9600 BPS (9600,8,NONE,1) - 0634 32r3As07 1440 LD (SER_BAUD),A ; - 0637 CDr14s06 1441 CALL INIT_UART ; INIT THE UART - 063A C9 1442 RET ; - 1443 ; - 1444 - 1445 ;__MTERM_INIT________________________________________________________________________________________ - 1446 ; - 1447 ; SETUP 8255, MODE 0, PORT A=OUT, PORT B=IN, PORT C=OUT/OUT - 1448 ; - 1449 ;____________________________________________________________________________________________________ - 063B 1450 MTERM_INIT: - 063B 3E 82 1451 LD A,#0x82 - 063D D3 63 1452 OUT (PIOCONT),A - 063F C9 1453 RET - 1454 - 1455 ;__KB_GET____________________________________________________________________________________________ - 1456 ; - 1457 ; GET A SINGLE KEY AND DECODE - 1458 ; - 1459 ;____________________________________________________________________________________________________ - 0640 1460 KB_GET: - 0640 E5 1461 PUSH HL ; STORE HL - 0641 1462 KB_GET_LOOP: ; WAIT FOR KEY - 0641 CDr67s06 1463 CALL KB_SCAN ; SCAN KB ONCE - 0644 FE 00 1464 CP #0 ; NULL? - 0646 28 F9 1465 JR Z,KB_GET_LOOP ; LOOP WHILE NOT ZERO - 0648 57 1466 LD D,A ; STORE A - 0649 3E 4F 1467 LD A,#0x4F ; SCAN ALL COL LINES - 064B D3 62 1468 OUT (PORTC),A ; SEND TO COLUMN LINES - 064D CDrB4s06 1469 CALL KB_SCAN_DELAY ; DELAY TO ALLOW LINES TO STABILIZE - 0650 1470 KB_CLEAR_LOOP: ; WAIT FOR KEY TO CLEAR - 0650 DB 61 1471 IN A,(PORTB) ; GET ROWS - 0652 FE 00 1472 CP #0 ; ANYTHING PRESSED? - 0654 20 FA 1473 JR NZ,KB_CLEAR_LOOP ; YES, EXIT - 0656 7A 1474 LD A,D ; RESTORE A - 0657 16 00 1475 LD D,#0x00 ; - 0659 21rE7s0C 1476 LD HL,#KB_DECODE ; POINT TO BEGINNING OF TABLE - 065C 1477 KB_GET_LLOOP: - 065C BE 1478 CP (HL) ; MATCH? - 065D 28 05 1479 JR Z,KB_GET_DONE ; FOUND, DONE - 065F 23 1480 INC HL - 0660 14 1481 INC D ; D + 1 - 0661 C2r5Cs06 1482 JP NZ,KB_GET_LLOOP ; NOT FOUND, LOOP UNTIL EOT - 0664 1483 KB_GET_DONE: - 0664 7A 1484 LD A,D ; RESULT INTO A - 0665 E1 1485 POP HL ; RESTORE HL - 0666 C9 1486 RET - 1487 - 1488 - 1489 - 1490 ;__KB_SCAN____________________________________________________________________________________________ - 1491 ; - 1492 ; SCAN KEYBOARD MATRIX FOR AN INPUT - 1493 ; - 1494 ;____________________________________________________________________________________________________ - 0667 1495 KB_SCAN: - 1496 - 0667 0E 00 1497 LD C,#0 - 0669 3E 41 1498 LD A,#0x41 ; SCAN COL ONE - 066B D3 62 1499 OUT (PORTC),A ; SEND TO COLUMN LINES - 066D CDrB4s06 1500 CALL KB_SCAN_DELAY ; DELAY TO ALLOW LINES TO STABILIZE - 0670 DB 61 1501 IN A,(PORTB) ; GET ROWS - 0672 FE 00 1502 CP #0x00 ; ANYTHING PRESSED? - 0674 20 34 1503 JR NZ,KB_SCAN_FOUND ; YES, EXIT - 1504 - 0676 0E 40 1505 LD C,#0x0040 - 0678 3E 42 1506 LD A,#0x42 ; SCAN COL TWO - 067A D3 62 1507 OUT (PORTC),A ; SEND TO COLUMN LINES - 067C CDrB4s06 1508 CALL KB_SCAN_DELAY ; DELAY TO ALLOW LINES TO STABILIZE - 067F DB 61 1509 IN A,(PORTB) ; GET ROWS - 0681 FE 00 1510 CP #0 ; ANYTHING PRESSED? - 0683 20 25 1511 JR NZ,KB_SCAN_FOUND ; YES, EXIT - 1512 - 0685 0E 80 1513 LD C,#0x0080 - 0687 3E 44 1514 LD A,#0x44 ; SCAN COL THREE - 0689 D3 62 1515 OUT (PORTC),A ; SEND TO COLUMN LINES - 068B CDrB4s06 1516 CALL KB_SCAN_DELAY ; DELAY TO ALLOW LINES TO STABILIZE - 068E DB 61 1517 IN A,(PORTB) ; GET ROWS - 0690 FE 00 1518 CP #0x00 ; ANYTHING PRESSED? - 0692 20 16 1519 JR NZ,KB_SCAN_FOUND ; YES, EXIT - 1520 - 0694 0E C0 1521 LD C,#0x00C0 ; - 0696 3E 48 1522 LD A,#0x48 ; SCAN COL FOUR - 0698 D3 62 1523 OUT (PORTC),A ; SEND TO COLUMN LINES - 069A CDrB4s06 1524 CALL KB_SCAN_DELAY ; DELAY TO ALLOW LINES TO STABILIZE - 069D DB 61 1525 IN A,(PORTB) ; GET ROWS - 069F FE 00 1526 CP #0x00 ; ANYTHING PRESSED? - 06A1 20 07 1527 JR NZ,KB_SCAN_FOUND ; YES, EXIT - 1528 - 06A3 3E 40 1529 LD A, #0x40 ; TURN OFF ALL COLUMNS - 06A5 D3 62 1530 OUT (PORTC),A ; SEND TO COLUMN LINES - 06A7 3E 00 1531 LD A, #0x00 ; RETURN NULL - 06A9 C9 1532 RET ; EXIT - 1533 - 06AA 1534 KB_SCAN_FOUND: - 06AA E6 3F 1535 AND #0x3F ; CLEAR TOP TWO BITS - 06AC B1 1536 OR C ; ADD IN ROW BITS - 06AD 4F 1537 LD C,A ; STORE VALUE - 06AE 3E 00 1538 LD A,#0x00 ; TURN OFF ALL COLUMNS - 06B0 D3 62 1539 OUT (PORTC),A ; SEND TO COLUMN LINES - 06B2 79 1540 LD A,C ; RESTORE VALUE - 06B3 C9 1541 RET - 1542 - 06B4 1543 PAUSE: - 06B4 1544 KB_SCAN_DELAY: - 06B4 00 1545 NOP - 06B5 00 1546 NOP - 06B6 00 1547 NOP - 06B7 00 1548 NOP - 06B8 00 1549 NOP - 06B9 00 1550 NOP - 06BA 00 1551 NOP - 06BB 00 1552 NOP - 06BC 00 1553 NOP - 06BD C9 1554 RET - 1555 - 1556 - 1557 - 1558 ;__HEXDISPLAY________________________________________________________________________________________ - 1559 ; - 1560 ; DISPLAY CONTENTS OF DISPLAYBUF IN DECODED HEX BITS 0-3 ARE DISPLAYED DIG, BIT 7 IS DP - 1561 ; - 1562 ;____________________________________________________________________________________________________ - 06BE 1563 HEXDISPLAY: - 06BE E5 1564 PUSH HL ; STORE HL - 06BF F5 1565 PUSH AF ; STORE AF - 06C0 C5 1566 PUSH BC ; STORE BC - 06C1 01 07 00 1567 LD BC,#0007 - 06C4 09 1568 ADD HL,BC - 06C5 06 08 1569 LD B,#0x08 ; SET DIGIT COUNT - 06C7 3E 40 1570 LD A,#0x40 ; SET CONTROL PORT 7218 TO OFF - 06C9 D3 62 1571 OUT (PORTC),A ; OUTPUT - 06CB CDrB4s06 1572 CALL PAUSE ; WAIT - 06CE 3E F0 1573 LD A,#0x0F0 ; SET CONTROL TO 1111 (DATA COMING, HEX DECODE,NO DECODE, NORMAL) - 06D0 D3 60 1574 OUT (PORTA),A ; OUTPUT TO PORT - 06D2 3E 80 1575 LD A,#0x80 ; STROBE WRITE PULSE WITH CONTROL=1 - 06D4 D3 62 1576 OUT (PORTC),A ; OUTPUT TO PORT - 06D6 CDrB4s06 1577 CALL PAUSE ; WAIT - 06D9 3E 40 1578 LD A,#0x40 ; SET CONTROL PORT 7218 TO OFF - 06DB D3 62 1579 OUT (PORTC),A ; OUTPUT - 06DD 1580 HEXDISPLAY_LP: - 06DD 7E 1581 LD A,(HL) ; GET DISPLAY DIGIT - 06DE CDrF8s06 1582 CALL DECODEDISPLAY ; DECODE DISPLAY - 06E1 D3 60 1583 OUT (PORTA),A ; OUT TO PORTA - 06E3 3E 00 1584 LD A,#0x00 ; SET WRITE STROBE - 06E5 D3 62 1585 OUT (PORTC),A ; OUT TO PORTC - 06E7 CDrB4s06 1586 CALL PAUSE ; DELAY - 06EA 3E 40 1587 LD A,#0x40 ; SET CONTROL PORT OFF - 06EC D3 62 1588 OUT (PORTC),A ; OUT TO PORTC - 06EE CDrB4s06 1589 CALL PAUSE ; WAIT - 06F1 2B 1590 DEC HL ; INC POINTER - 06F2 10 E9 1591 DJNZ HEXDISPLAY_LP ; LOOP FOR NEXT DIGIT - 06F4 C1 1592 POP BC ; RESTORE BC - 06F5 F1 1593 POP AF ; RESTORE AF - 06F6 E1 1594 POP HL ; RESTORE HL - 06F7 C9 1595 RET - 1596 - 1597 ;__DECODEDISPLAY_____________________________________________________________________________________ - 1598 ; - 1599 ; DISPLAY CONTENTS OF DISPLAYBUF IN DECODED HEX BITS 0-3 ARE DISPLAYED DIG, BIT 7 IS DP - 1600 ; - 1601 ;____________________________________________________________________________________________________ - 06F8 1602 DECODEDISPLAY: - 06F8 C5 1603 PUSH BC ; STORE BC - 06F9 E5 1604 PUSH HL ; STORE HL - 06FA 21rFFs0C 1605 LD HL,#SEGDECODE ; POINT HL TO DECODE TABLE - 06FD 06 00 1606 LD B,#0x00 ; RESET HIGH BYTE - 06FF 4F 1607 LD C,A ; CHAR INTO LOW BYTE - 0700 09 1608 ADD HL,BC ; SET TABLE POINTER - 0701 7E 1609 LD A,(HL) ; GET VALUE - 0702 E1 1610 POP HL ; RESTORE HL - 0703 C1 1611 POP BC ; RESTORE BC - 0704 C9 1612 RET - 1613 - 1614 - 1615 ;__SEGDISPLAY________________________________________________________________________________________ - 1616 ; - 1617 ; DISPLAY CONTENTS OF DISPLAYBUF IN DECODED HEX BITS 0-3 ARE DISPLAYED DIG, BIT 7 IS DP - 1618 ; - 1619 ;____________________________________________________________________________________________________ - 0705 1620 SEGDISPLAY: - 0705 F5 1621 PUSH AF ; STORE AF - 0706 C5 1622 PUSH BC ; STORE BC - 0707 01 07 00 1623 LD BC,#0x0007 - 070A 09 1624 ADD HL,BC - 070B 06 08 1625 LD B,#0x08 ; SET DIGIT COUNT - 070D 3E 40 1626 LD A,#0x40 ; SET CONTROL PORT 7218 TO OFF - 070F D3 62 1627 OUT (PORTC),A ; OUTPUT - 0711 CDrB4s06 1628 CALL PAUSE ; WAIT - 0714 3E F0 1629 LD A,#0x0F0 ; SET CONTROL TO 1111 (DATA COMING, HEX DECODE,NO DECODE, NORMAL) - 0716 D3 60 1630 OUT (PORTA),A ; OUTPUT TO PORT - 0718 3E 80 1631 LD A,#0x80 ; STROBE WRITE PULSE WITH CONTROL=1 - 071A D3 62 1632 OUT (PORTC),A ; OUTPUT TO PORT - 071C CDrB4s06 1633 CALL PAUSE ; WAIT - 071F 3E 40 1634 LD A,#0x40 ; SET CONTROL PORT 7218 TO OFF - 0721 D3 62 1635 OUT (PORTC),A ; OUTPUT - 0723 1636 SEGDISPLAY_LP: - 0723 7E 1637 LD A,(HL) ; GET DISPLAY DIGIT - 0724 D3 60 1638 OUT (PORTA),A ; OUT TO PORTA - 0726 3E 00 1639 LD A,#0x00 ; SET WRITE STROBE - 0728 D3 62 1640 OUT (PORTC),A ; OUT TO PORTC - 072A CDrB4s06 1641 CALL PAUSE ; DELAY - 072D 3E 40 1642 LD A,#0x40 ; SET CONTROL PORT OFF - 072F D3 62 1643 OUT (PORTC),A ; OUT TO PORTC - 0731 CDrB4s06 1644 CALL PAUSE ; WAIT - 0734 2B 1645 DEC HL ; INC POINTER - 0735 10 EC 1646 DJNZ SEGDISPLAY_LP ; LOOP FOR NEXT DIGIT - 0737 C1 1647 POP BC ; RESTORE BC - 0738 F1 1648 POP AF ; RESTORE AF - 0739 C9 1649 RET - 1650 - 1651 ; - 1652 ;__WORK_AREA___________________________________________________________________________________________________________________ - 1653 ; - 1654 ; RESERVED RAM FOR MONITOR WORKING AREA - 1655 ;_____________________________________________________________________________________________________________________________ - 1656 ; - 073A 1657 SER_BAUD: .DS 1 ; SPECIFY DESIRED UART COM RATE IN BPS - 073B 20 20 20 20 20 20 1658 KEYBUF: .ascii " " - 20 20 20 20 20 20 - 20 20 20 20 20 20 - 20 20 20 20 20 20 - 20 20 20 20 20 20 - 20 20 20 20 - 075D 20 20 20 20 20 20 1659 .ascii " " - 20 20 20 20 20 20 - 20 20 20 20 20 20 - 20 20 20 20 20 20 - 20 20 20 20 20 20 - 20 20 20 20 20 20 - 20 20 20 20 20 20 - 20 20 20 20 - 078B 00 00 00 00 00 00 1660 DISPLAYBUF: .DB 00,00,00,00,00,00,00,00 - 00 00 - 0793 01 1661 IDEDEVICE: .DB 1 ; IDE DRIVE SELECT FLAG (00H=PRIAMRY, 10H = SECONDARY) - 0794 1662 IDE_SECTOR_BUFFER: - 0794 1663 .DS 0x00200 - 1664 - 1665 - 1666 - 1667 - 1668 ; - 1669 ;__TEXT_STRINGS_________________________________________________________________________________________________________________ - 1670 ; - 1671 ; SYSTEM TEXT STRINGS - 1672 ;_____________________________________________________________________________________________________________________________ - 1673 ; - 0994 1674 TCRLF: - 0994 0D 0A FF 1675 .DB CR,LF,ENDT - 1676 - 0997 1677 PROMPT: - 0997 0D 0A 1678 .DB CR,LF - 0999 3E 1679 .ascii ">" - 099A FF 1680 .DB ENDT - 1681 - 099B 1682 TXT_READY: - 099B 0D 0A 1683 .DB CR,LF - 099D 20 20 20 20 20 20 1684 .ascii " NN NN 8888 VV VV EEEEEEEEEE MM MM" - 20 20 20 4E 4E 20 - 20 20 20 20 20 4E - 4E 20 20 20 20 20 - 20 38 38 38 38 20 - 20 20 20 20 20 56 - 56 20 20 20 20 20 - 20 56 56 20 20 20 - 20 45 45 45 45 45 - 45 45 45 45 45 20 - 20 20 4D 4D 20 20 - 20 20 20 20 20 20 - 20 20 4D 4D - 09E9 0D 0A 1685 .DB CR,LF - 09EB 20 20 20 20 20 20 1686 .ascii " NNNN NN 88 88 VV VV EE MMMM MMMM" - 20 20 4E 4E 4E 4E - 20 20 20 20 4E 4E - 20 20 20 20 38 38 - 20 20 20 20 38 38 - 20 20 20 20 56 56 - 20 20 20 20 20 20 - 56 56 20 20 20 20 - 45 45 20 20 20 20 - 20 20 20 20 20 20 - 20 4D 4D 4D 4D 20 - 20 20 20 20 20 4D - 4D 4D 4D - 0A36 0D 0A 1687 .DB CR,LF - 0A38 20 20 20 20 20 20 1688 .ascii " NN NN NN 88 88 VV VV EE MM MM MM MM" - 20 4E 4E 20 20 4E - 4E 20 20 4E 4E 20 - 20 20 20 38 38 20 - 20 20 20 38 38 20 - 20 20 20 56 56 20 - 20 20 20 20 20 56 - 56 20 20 20 20 45 - 45 20 20 20 20 20 - 20 20 20 20 20 20 - 4D 4D 20 20 4D 4D - 20 20 4D 4D 20 20 - 4D 4D - 0A82 0D 0A 1689 .DB CR,LF - 0A84 20 20 20 20 20 20 1690 .ascii " NN NNNN 88 88 VV VV EE MM MM MM" - 4E 4E 20 20 20 20 - 4E 4E 4E 4E 20 20 - 20 20 38 38 20 20 - 20 20 38 38 20 20 - 20 20 56 56 20 20 - 20 20 20 20 56 56 - 20 20 20 20 45 45 - 20 20 20 20 20 20 - 20 20 20 20 20 4D - 4D 20 20 20 20 4D - 4D 20 20 20 20 4D - 4D - 0ACD 0D 0A 1691 .DB CR,LF - 0ACF 20 20 20 20 20 4E 1692 .ascii " NN NN 8888 VV VV EEEEEEE MM MM" - 4E 20 20 20 20 20 - 20 4E 4E 20 20 20 - 20 20 20 38 38 38 - 38 20 20 20 20 20 - 20 56 56 20 20 20 - 20 20 20 56 56 20 - 20 20 20 45 45 45 - 45 45 45 45 20 20 - 20 20 20 20 4D 4D - 20 20 20 20 20 20 - 20 20 20 20 4D 4D - 0B17 0D 0A 1693 .DB CR,LF - 0B19 20 20 20 20 4E 4E 1694 .ascii " NN NN 88 88 VV VV EE MM MM" - 20 20 20 20 20 20 - 4E 4E 20 20 20 20 - 38 38 20 20 20 20 - 38 38 20 20 20 20 - 20 56 56 20 20 20 - 20 56 56 20 20 20 - 20 20 45 45 20 20 - 20 20 20 20 20 20 - 20 20 20 4D 4D 20 - 20 20 20 20 20 20 - 20 20 20 4D 4D - 0B60 0D 0A 1695 .DB CR,LF - 0B62 20 20 20 4E 4E 20 1696 .ascii " NN NN 88 88 VV VV EE MM MM" - 20 20 20 20 20 4E - 4E 20 20 20 20 38 - 38 20 20 20 20 38 - 38 20 20 20 20 20 - 20 56 56 20 20 56 - 56 20 20 20 20 20 - 20 45 45 20 20 20 - 20 20 20 20 20 20 - 20 20 4D 4D 20 20 - 20 20 20 20 20 20 - 20 20 4D 4D - 0BA8 0D 0A 1697 .DB CR,LF - 0BAA 20 20 4E 4E 20 20 1698 .ascii " NN NN 88 88 VVV EE MM MM" - 20 20 20 20 4E 4E - 20 20 20 20 38 38 - 20 20 20 20 38 38 - 20 20 20 20 20 20 - 20 20 56 56 56 20 - 20 20 20 20 20 20 - 45 45 20 20 20 20 - 20 20 20 20 20 20 - 20 4D 4D 20 20 20 - 20 20 20 20 20 20 - 20 4D 4D - 0BEF 0D 0A 1699 .DB CR,LF - 0BF1 20 4E 4E 20 20 20 1700 .ascii " NN NN 8888 V EEEEEEEEEE MM MM S B C" - 20 20 20 4E 4E 20 - 20 20 20 20 20 38 - 38 38 38 20 20 20 - 20 20 20 20 20 20 - 20 20 56 20 20 20 - 20 20 20 20 20 45 - 45 45 45 45 45 45 - 45 45 45 20 20 20 - 4D 4D 20 20 20 20 - 20 20 20 20 20 20 - 4D 4D 20 20 20 20 - 53 20 42 20 43 - 0C3E 0D 0A 1701 .DB CR,LF - 0C40 0D 0A 1702 .DB CR,LF - 0C42 20 2A 2A 2A 2A 2A 1703 .ascii " ****************************************************************************" - 2A 2A 2A 2A 2A 2A - 2A 2A 2A 2A 2A 2A - 2A 2A 2A 2A 2A 2A - 2A 2A 2A 2A 2A 2A - 2A 2A 2A 2A 2A 2A - 2A 2A 2A 2A 2A 2A - 2A 2A 2A 2A 2A 2A - 2A 2A 2A 2A 2A 2A - 2A 2A 2A 2A 2A 2A - 2A 2A 2A 2A 2A 2A - 2A 2A 2A 2A 2A 2A - 2A 2A 2A 2A 2A - 0C8F 0D 0A 1704 .DB CR,LF - 0C91 4D 4F 4E 49 54 4F 1705 .ascii "MONITOR READY " - 52 20 52 45 41 44 - 59 20 - 0C9F 0D 0A FF 1706 .DB CR,LF,ENDT - 1707 - 0CA2 1708 TXT_COMMAND: - 0CA2 0D 0A 1709 .DB CR,LF - 0CA4 55 4E 4B 4E 4F 57 1710 .ascii "UNKNOWN COMMAND." - 4E 20 43 4F 4D 4D - 41 4E 44 2E - 0CB4 FF 1711 .DB ENDT - 1712 - 0CB5 1713 TXT_CKSUMERR: - 0CB5 0D 0A 1714 .DB CR,LF - 0CB7 43 48 45 43 4B 53 1715 .ascii "CHECKSUM ERROR." - 55 4D 20 45 52 52 - 4F 52 2E - 0CC6 FF 1716 .DB ENDT - 0CC7 1717 CPUUP: - 0CC7 84 EE BB 80 BB EE 1718 .DB 0x084,0x0EE,0x0BB,0x080,0x0BB,0x0EE,0x0CB,0x084 - CB 84 - 0CCF 1719 ADDR: - 0CCF 00 00 00 00 8C BD 1720 .DB 0x00,0x00,0x00,0x00,0x08C,0x0BD,0x0BD,0x0FE - BD FE - 1721 - 1722 - 0CD7 1723 PORT: - 0CD7 00 00 80 80 94 8C 1724 .DB 0x00,0x00,0x80,0x80,0x094,0x08C,0x09D,0x0EE - 9D EE - 0CDF 1725 SEC: - 0CDF 80 80 80 80 80 CB 1726 .DB 0x80,0x80,0x80,0x80,0x80,0x0CB,0x0CF,0x0D7 - CF D7 - 1727 - 1728 - 1729 ;_KB DECODE TABLE__________________________________________________________________________________________________________ - 1730 ; - 1731 ; - 0CE7 1732 KB_DECODE: - 1733 ; 0 1 2 3 4 5 6 7 8 9 A B C D E F - 0CE7 41 02 42 82 04 44 1734 .DB 0x41,0x02,0x42,0x82,0x04,0x44,0x84,0x08,0x48,0x88,0x10,0x50,0x90,0x20,0x60,0x0A0 - 84 08 48 88 10 50 - 90 20 60 A0 - 1735 ; FW BK CL EN DP EX GO BO - 0CF7 01 81 C1 C2 C4 C8 1736 .DB 0x01,0x81,0x0C1,0x0C2,0x0C4,0x0C8,0x0D0,0x0E0 - D0 E0 - 1737 ; - 1738 ; F-KEYS, - 1739 ; FW = FORWARD - 1740 ; BK = BACKWARD - 1741 ; CL = CLEAR - 1742 ; EN = ENTER - 1743 ; DP = DEPOSIT (INTO MEM) - 1744 ; EX = EXAMINE (MEM) - 1745 ; GO = GO - 1746 ; BO = BOOT - 1747 ;_________________________________________________________________________________________________________________________ - 1748 ;_HEX 7_SEG_DECODE_TABLE__________________________________________________________________________________________________ - 1749 ; - 1750 ; 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F, ,- - 1751 ; AND WITH 7FH TO TURN ON DP - 1752 ;_________________________________________________________________________________________________________________________ - 0CFF 1753 SEGDECODE: - 0CFF FB B0 ED F5 B6 D7 1754 .DB 0x0FB,0x0B0,0x0ED,0x0F5,0x0B6,0x0D7,0x0DF,0x0F0,0x0FF,0x0F7,0x0FE,0x09F,0x0CB,0x0BD,0x0CF,0x0CE,0x080,0x084,0x00,0x0EE,0x09D - DF F0 FF F7 FE 9F - CB BD CF CE 80 84 - 00 EE 9D - 1755 - 1756 ;********************* END OF PROGRAM *********************************** - 1757 - 1758 ;dwg; .ORG 08FFFh - 1759 ;dwg; .DB 000h - 1760 ;dwg; .END - 1761 - 0D14 1762 _dbgmon_end:: - 1763 .area _CODE - 1764 .area _CABS diff --git a/doug/src/dbgmon.rel b/doug/src/dbgmon.rel deleted file mode 100755 index e2e39a62..00000000 --- a/doug/src/dbgmon.rel +++ /dev/null @@ -1,838 +0,0 @@ -XL -H 8 areas 4 global symbols -M dbgmon -O -mz80 -S .__.ABS. Def0000 -A _CODE size 0 flags 0 addr 0 -A _DATA size 0 flags 0 addr 0 -A _OVERLAY size 0 flags 0 addr 0 -A _HOME size 0 flags 0 addr 0 -A _GSINIT size 0 flags 0 addr 0 -A _GSFINAL size 0 flags 0 addr 0 -A _DBGMON size D14 flags 0 addr 0 -S _dbgmon Def0000 -S _dbgmon_start Def0000 -S _dbgmon_end Def0D14 -A _CABS size 0 flags 0 addr 0 -T 00 00 -R 00 00 06 00 -T 00 00 -R 00 00 06 00 -T 00 00 31 FF CF CD 32 06 CD 3B 06 21 C7 0C CD -R 00 00 06 00 00 06 06 00 00 09 06 00 00 0C 06 00 -T 0D 00 05 07 -R 00 00 06 00 00 02 06 00 -T 0F 00 -R 00 00 06 00 -T 0F 00 CD 40 06 FE 10 CA 3C 00 FE 11 CA 94 00 FE -R 00 00 06 00 00 03 06 00 00 08 06 00 00 0D 06 00 -T 1D 00 14 CA D0 00 FE 15 CA 24 01 FE 16 CA CC 00 -R 00 00 06 00 00 04 06 00 00 09 06 00 00 0E 06 00 -T 2B 00 FE 17 CA 33 00 18 DD -R 00 00 06 00 00 05 06 00 -T 32 00 -R 00 00 06 00 -T 32 00 C9 -R 00 00 06 00 -T 33 00 -R 00 00 06 00 -T 33 00 3E 00 D3 7C D3 78 C3 00 00 -R 00 00 06 00 -T 3C 00 -R 00 00 06 00 -T 3C 00 CD 6C 02 -R 00 00 06 00 00 03 06 00 -T 3F 00 -R 00 00 06 00 -T 3F 00 4F CB 3F CB 3F CB 3F CB 3F 32 90 07 79 E6 -R 00 00 06 00 00 0C 06 00 -T 4D 00 0F 32 8F 07 ED 78 4F CB 3F CB 3F CB 3F CB -R 00 00 06 00 00 04 06 00 -T 5B 00 3F 32 8C 07 79 E6 0F 32 8B 07 3E 10 32 -R 00 00 06 00 00 04 06 00 00 0A 06 00 -T 68 00 8D 07 32 8E 07 3E 13 32 92 07 3E 14 32 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 0A 06 00 -T 75 00 91 07 21 8B 07 CD BE 06 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 7D 00 -R 00 00 06 00 -T 7D 00 CD 40 06 FE 12 CA 8B 00 FE 10 28 B3 18 F2 -R 00 00 06 00 00 03 06 00 00 08 06 00 -T 8B 00 -R 00 00 06 00 -T 8B 00 21 C7 0C CD 05 07 C3 0F 00 -R 00 00 06 00 00 03 06 00 00 06 06 00 00 09 06 00 -T 94 00 -R 00 00 06 00 -T 94 00 CD 6C 02 -R 00 00 06 00 00 03 06 00 -T 97 00 -R 00 00 06 00 -T 97 00 4F CB 3F CB 3F CB 3F CB 3F 32 90 07 79 E6 -R 00 00 06 00 00 0C 06 00 -T A5 00 0F 32 8F 07 3E 10 32 8D 07 32 8E 07 3E 13 -R 00 00 06 00 00 04 06 00 00 09 06 00 00 0C 06 00 -T B3 00 32 92 07 3E 14 32 91 07 21 8B 07 CD -R 00 00 06 00 00 03 06 00 00 08 06 00 00 0B 06 00 -T BF 00 CF 02 ED 79 21 C7 0C CD 05 07 C3 -R 00 00 06 00 00 02 06 00 00 07 06 00 00 0A 06 00 -T CA 00 0F 00 -R 00 00 06 00 00 02 06 00 -T CC 00 -R 00 00 06 00 -T CC 00 CD 89 01 E9 -R 00 00 06 00 00 03 06 00 -T D0 00 -R 00 00 06 00 -T D0 00 CD 89 01 E5 -R 00 00 06 00 00 03 06 00 -T D4 00 -R 00 00 06 00 -T D4 00 7C CB 3F CB 3F CB 3F CB 3F 32 92 07 7C E6 -R 00 00 06 00 00 0C 06 00 -T E2 00 0F 32 91 07 7D CB 3F CB 3F CB 3F CB 3F 32 -R 00 00 06 00 00 04 06 00 -T F0 00 90 07 7D E6 0F 32 8F 07 3E 10 32 8E 07 21 -R 00 00 06 00 00 02 06 00 00 08 06 00 00 0D 06 00 -T FE 00 8B 07 CD CF 02 E1 77 -R 00 00 06 00 00 02 06 00 00 05 06 00 -T 05 01 -R 00 00 06 00 -T 05 01 CD 40 06 FE 12 CA 1B 01 FE 13 28 06 FE 14 -R 00 00 06 00 00 03 06 00 00 08 06 00 -T 13 01 28 BB 18 EE -R 00 00 06 00 -T 17 01 -R 00 00 06 00 -T 17 01 23 E5 18 B9 -R 00 00 06 00 -T 1B 01 -R 00 00 06 00 -T 1B 01 21 C7 0C CD 05 07 C3 0F 00 -R 00 00 06 00 00 03 06 00 00 06 06 00 00 09 06 00 -T 24 01 -R 00 00 06 00 -T 24 01 CD 89 01 E5 -R 00 00 06 00 00 03 06 00 -T 28 01 -R 00 00 06 00 -T 28 01 7C CB 3F CB 3F CB 3F CB 3F 32 92 07 7C E6 -R 00 00 06 00 00 0C 06 00 -T 36 01 0F 32 91 07 7D CB 3F CB 3F CB 3F CB 3F 32 -R 00 00 06 00 00 04 06 00 -T 44 01 90 07 7D E6 0F 32 8F 07 3E 10 32 8E 07 7E -R 00 00 06 00 00 02 06 00 00 08 06 00 00 0D 06 00 -T 52 01 CB 3F CB 3F CB 3F CB 3F 32 8C 07 7E E6 0F -R 00 00 06 00 00 0B 06 00 -T 60 01 32 8B 07 21 8B 07 CD BE 06 E1 -R 00 00 06 00 00 03 06 00 00 06 06 00 00 09 06 00 -T 6A 01 -R 00 00 06 00 -T 6A 01 CD 40 06 FE 12 CA 80 01 FE 13 28 06 FE 15 -R 00 00 06 00 00 03 06 00 00 08 06 00 -T 78 01 28 AA 18 EE -R 00 00 06 00 -T 7C 01 -R 00 00 06 00 -T 7C 01 23 E5 18 A8 -R 00 00 06 00 -T 80 01 -R 00 00 06 00 -T 80 01 21 C7 0C CD 05 07 C3 0F 00 -R 00 00 06 00 00 03 06 00 00 06 06 00 00 09 06 00 -T 89 01 -R 00 00 06 00 -T 89 01 C5 18 6A -R 00 00 06 00 -T 8C 01 -R 00 00 06 00 -T 8C 01 21 CF 0C CD 05 07 -R 00 00 06 00 00 03 06 00 00 06 06 00 -T 92 01 -R 00 00 06 00 -T 92 01 CD 40 06 FE 10 FA DD 01 FE 13 28 06 FE 12 -R 00 00 06 00 00 03 06 00 00 08 06 00 -T A0 01 28 54 18 EE -R 00 00 06 00 -T A4 01 -R 00 00 06 00 -T A4 01 21 00 00 3A 8C 07 CB 27 CB 27 CB 27 CB 27 -R 00 00 06 00 00 06 06 00 -T B2 01 4F 3A 8B 07 E6 0F B1 6F 3A 8E 07 CB 27 CB -R 00 00 06 00 00 04 06 00 00 0B 06 00 -T C0 01 27 CB 27 CB 27 4F 3A 8D 07 E6 0F B1 67 3E -R 00 00 06 00 00 09 06 00 -T CE 01 10 32 8B 07 32 8C 07 32 8D 07 32 -R 00 00 06 00 00 04 06 00 00 07 06 00 00 0A 06 00 -T D9 01 8E 07 C1 C9 -R 00 00 06 00 00 02 06 00 -T DD 01 -R 00 00 06 00 -T DD 01 4F 3A 8D 07 32 8E 07 3A 8C 07 32 -R 00 00 06 00 00 04 06 00 00 07 06 00 00 0A 06 00 -T E8 01 8D 07 3A 8B 07 32 8C 07 79 32 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T F2 01 8B 07 18 0E -R 00 00 06 00 00 02 06 00 -T F6 01 -R 00 00 06 00 -T F6 01 3E 12 32 8B 07 32 8C 07 32 8D 07 32 -R 00 00 06 00 00 05 06 00 00 08 06 00 00 0B 06 00 -T 02 02 8E 07 -R 00 00 06 00 00 02 06 00 -T 04 02 -R 00 00 06 00 -T 04 02 3A 8B 07 CD F8 06 32 CF 0C 3A -R 00 00 06 00 00 03 06 00 00 06 06 00 00 09 06 00 -T 0E 02 8C 07 CD F8 06 32 D0 0C 3A -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 17 02 8D 07 CD F8 06 32 D1 0C 3A -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 20 02 8E 07 CD F8 06 32 D2 0C C3 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 29 02 8C 01 -R 00 00 06 00 00 02 06 00 -T 2B 02 -R 00 00 06 00 -T 2B 02 C5 E5 7C CB 3F CB 3F CB 3F CB 3F E6 0F CD -R 00 00 06 00 -T 39 02 F8 06 32 E2 0C 7C E6 0F CD F8 06 32 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 0B 06 00 -T 45 02 E1 0C 7D E6 F0 CB 3F CB 3F CB 3F CB 3F E6 -R 00 00 06 00 00 02 06 00 -T 53 02 0F CD F8 06 32 E0 0C 7D E6 0F CD F8 06 32 -R 00 00 06 00 00 04 06 00 00 07 06 00 00 0D 06 00 -T 61 02 DF 0C 21 DF 0C CD 05 07 E1 C1 C9 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T 6C 02 -R 00 00 06 00 -T 6C 02 C5 18 43 -R 00 00 06 00 -T 6F 02 -R 00 00 06 00 -T 6F 02 21 D7 0C CD 05 07 -R 00 00 06 00 00 03 06 00 00 06 06 00 -T 75 02 -R 00 00 06 00 -T 75 02 CD 40 06 FE 10 FA A5 02 FE 13 28 06 FE 12 -R 00 00 06 00 00 03 06 00 00 08 06 00 -T 83 02 28 2D 18 EE -R 00 00 06 00 -T 87 02 -R 00 00 06 00 -T 87 02 3A 8C 07 CB 27 CB 27 CB 27 CB 27 4F 3A -R 00 00 06 00 00 03 06 00 -T 94 02 8B 07 E6 0F B1 4F 3E 10 32 8B 07 32 8C 07 -R 00 00 06 00 00 02 06 00 00 0B 06 00 00 0E 06 00 -T A2 02 79 C1 C9 -R 00 00 06 00 -T A5 02 -R 00 00 06 00 -T A5 02 4F 3A 8B 07 32 8C 07 79 32 8B 07 18 08 -R 00 00 06 00 00 04 06 00 00 07 06 00 00 0B 06 00 -T B2 02 -R 00 00 06 00 -T B2 02 3E 12 32 8B 07 32 8C 07 -R 00 00 06 00 00 05 06 00 00 08 06 00 -T BA 02 -R 00 00 06 00 -T BA 02 3A 8B 07 CD F8 06 32 D7 0C 3A -R 00 00 06 00 00 03 06 00 00 06 06 00 00 09 06 00 -T C4 02 8C 07 CD F8 06 32 D8 0C C3 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 08 06 00 -T CD 02 6F 02 -R 00 00 06 00 00 02 06 00 -T CF 02 -R 00 00 06 00 -T CF 02 C5 18 40 -R 00 00 06 00 -T D2 02 -R 00 00 06 00 -T D2 02 CD BE 06 -R 00 00 06 00 00 03 06 00 -T D5 02 -R 00 00 06 00 -T D5 02 CD 40 06 FE 10 FA 05 03 FE 13 28 06 FE 12 -R 00 00 06 00 00 03 06 00 00 08 06 00 -T E3 02 28 2D 18 EE -R 00 00 06 00 -T E7 02 -R 00 00 06 00 -T E7 02 3A 8C 07 CB 27 CB 27 CB 27 CB 27 4F 3A -R 00 00 06 00 00 03 06 00 -T F4 02 8B 07 E6 0F B1 4F 3E 10 32 8B 07 32 8C 07 -R 00 00 06 00 00 02 06 00 00 0B 06 00 00 0E 06 00 -T 02 03 79 C1 C9 -R 00 00 06 00 -T 05 03 -R 00 00 06 00 -T 05 03 4F 3A 8B 07 32 8C 07 79 32 8B 07 18 C0 -R 00 00 06 00 00 04 06 00 00 07 06 00 00 0B 06 00 -T 12 03 -R 00 00 06 00 -T 12 03 3E 12 32 8B 07 32 8C 07 C3 D2 02 -R 00 00 06 00 00 05 06 00 00 08 06 00 00 0B 06 00 -T 1D 03 -R 00 00 06 00 -T 1D 03 31 FF CF CD 32 06 AF E5 21 9B 09 CD 8A 04 -R 00 00 06 00 00 06 06 00 00 0B 06 00 00 0E 06 00 -T 2B 03 E1 -R 00 00 06 00 -T 2C 03 -R 00 00 06 00 -T 2C 03 CD 81 04 21 3B 07 CD 81 03 21 -R 00 00 06 00 00 03 06 00 00 06 06 00 00 09 06 00 -T 36 03 3B 07 7E 23 FE 42 CA 33 00 FE 52 CA 98 04 -R 00 00 06 00 00 02 06 00 00 09 06 00 00 0E 06 00 -T 44 03 FE 50 CA 9D 04 FE 4F CA 63 04 FE 48 CA -R 00 00 06 00 00 05 06 00 00 0A 06 00 -T 51 03 30 05 FE 49 CA 71 04 FE 44 CA D4 04 FE 4B -R 00 00 06 00 00 02 06 00 00 07 06 00 00 0C 06 00 -T 5F 03 CA 74 03 FE 4D CA 9C 05 FE 46 CA DD 05 21 -R 00 00 06 00 00 03 06 00 00 08 06 00 00 0D 06 00 -T 6D 03 A2 0C CD 8A 04 18 B8 -R 00 00 06 00 00 02 06 00 00 05 06 00 -T 74 03 -R 00 00 06 00 -T 74 03 CD B4 03 CD C8 03 FE 1B 20 F6 C3 2C 03 -R 00 00 06 00 00 03 06 00 00 06 06 00 00 0D 06 00 -T 81 03 -R 00 00 06 00 -T 81 03 0E 00 D5 -R 00 00 06 00 -T 84 03 -R 00 00 06 00 -T 84 03 CD B4 03 CD C8 03 FE 0D 28 22 FE 08 20 16 -R 00 00 06 00 00 03 06 00 00 06 06 00 -T 92 03 79 FE 00 28 ED 2B 0D 3E 00 77 3E 20 CD -R 00 00 06 00 -T 9F 03 C8 03 3E 08 CD C8 03 18 DC -R 00 00 06 00 00 02 06 00 00 07 06 00 -T A8 03 -R 00 00 06 00 -T A8 03 77 23 0C 79 FE 4D 20 D4 -R 00 00 06 00 -T B0 03 -R 00 00 06 00 -T B0 03 36 00 D1 C9 -R 00 00 06 00 -T B4 03 -R 00 00 06 00 -T B4 03 DB 6D CB 47 CA B4 03 DB 68 E6 7F FE 41 D8 -R 00 00 06 00 00 07 06 00 -T C2 03 FE 7B D0 E6 5F C9 -R 00 00 06 00 -T C8 03 -R 00 00 06 00 -T C8 03 F5 -R 00 00 06 00 -T C9 03 -R 00 00 06 00 -T C9 03 DB 6D CB 6F CA C9 03 F1 D3 68 C9 -R 00 00 06 00 00 07 06 00 -T D4 03 -R 00 00 06 00 -T D4 03 E5 21 94 09 CD 8A 04 E1 C9 -R 00 00 06 00 00 04 06 00 00 07 06 00 -T DD 03 -R 00 00 06 00 -T DD 03 D5 CD E9 03 57 CD E9 03 6F 62 D1 C9 -R 00 00 06 00 00 04 06 00 00 08 06 00 -T E9 03 -R 00 00 06 00 -T E9 03 C5 CD FC 03 CB 07 CB 07 CB 07 CB 07 47 CD -R 00 00 06 00 00 04 06 00 -T F7 03 FC 03 80 C1 C9 -R 00 00 06 00 00 02 06 00 -T FC 03 -R 00 00 06 00 -T FC 03 7E 23 FE 40 30 03 E6 0F C9 -R 00 00 06 00 -T 05 04 -R 00 00 06 00 -T 05 04 E6 0F C6 09 C9 -R 00 00 06 00 -T 0A 04 -R 00 00 06 00 -T 0A 04 C5 CD 1D 04 CB 07 CB 07 CB 07 CB 07 47 CD -R 00 00 06 00 00 04 06 00 -T 18 04 1D 04 80 C1 C9 -R 00 00 06 00 00 02 06 00 -T 1D 04 -R 00 00 06 00 -T 1D 04 CD B4 03 23 FE 40 30 E0 E6 0F C9 -R 00 00 06 00 00 03 06 00 -T 28 04 -R 00 00 06 00 -T 28 04 C5 47 CB 07 CB 07 CB 07 CB 07 E6 0F C6 30 -R 00 00 06 00 -T 36 04 FE 3A 38 02 C6 07 -R 00 00 06 00 -T 3C 04 -R 00 00 06 00 -T 3C 04 CD C8 03 78 E6 0F C6 30 FE 3A 38 02 C6 07 -R 00 00 06 00 00 03 06 00 -T 4A 04 -R 00 00 06 00 -T 4A 04 CD C8 03 C1 C9 -R 00 00 06 00 00 03 06 00 -T 4F 04 -R 00 00 06 00 -T 4F 04 F5 3E 20 CD C8 03 F1 C9 -R 00 00 06 00 00 06 06 00 -T 57 04 -R 00 00 06 00 -T 57 04 7C CD 28 04 7D CD 28 04 CD 4F 04 C9 -R 00 00 06 00 00 04 06 00 00 08 06 00 00 0B 06 00 -T 63 04 -R 00 00 06 00 -T 63 04 -R 00 00 06 00 -T 63 04 23 CD E9 03 4F 23 CD E9 03 -R 00 00 06 00 00 04 06 00 00 09 06 00 -T 6C 04 -R 00 00 06 00 -T 6C 04 ED 79 C3 2C 03 -R 00 00 06 00 00 05 06 00 -T 71 04 -R 00 00 06 00 -T 71 04 23 CD E9 03 4F CD D4 03 ED 78 CD 28 04 C3 -R 00 00 06 00 00 04 06 00 00 08 06 00 00 0D 06 00 -T 7F 04 2C 03 -R 00 00 06 00 00 02 06 00 -T 81 04 -R 00 00 06 00 -T 81 04 E5 21 97 09 CD 8A 04 E1 C9 -R 00 00 06 00 00 04 06 00 00 07 06 00 -T 8A 04 -R 00 00 06 00 -T 8A 04 -R 00 00 06 00 -T 8A 04 7E FE FF CA 97 04 CD C8 03 23 C3 8A 04 -R 00 00 06 00 00 06 06 00 00 09 06 00 00 0D 06 00 -T 97 04 -R 00 00 06 00 -T 97 04 C9 -R 00 00 06 00 -T 98 04 -R 00 00 06 00 -T 98 04 23 CD DD 03 E9 -R 00 00 06 00 00 04 06 00 -T 9D 04 -R 00 00 06 00 -T 9D 04 23 E5 CD DD 03 54 5D E1 23 23 23 23 23 -R 00 00 06 00 00 05 06 00 -T AA 04 -R 00 00 06 00 -T AA 04 CD E9 03 12 13 CD 81 04 3E 50 CD C8 03 CD -R 00 00 06 00 00 03 06 00 00 08 06 00 00 0D 06 00 -T B8 04 4F 04 62 6B CD 57 04 21 3B 07 CD -R 00 00 06 00 00 02 06 00 00 07 06 00 00 0A 06 00 -T C3 04 81 03 21 3B 07 7E FE 00 CA D1 04 C3 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 0B 06 00 -T CF 04 AA 04 -R 00 00 06 00 00 02 06 00 -T D1 04 -R 00 00 06 00 -T D1 04 C3 2C 03 -R 00 00 06 00 00 03 06 00 -T D4 04 -R 00 00 06 00 -T D4 04 23 E5 CD DD 03 54 5D E1 D5 23 23 23 23 23 -R 00 00 06 00 00 05 06 00 -T E2 04 CD DD 03 23 EB E1 -R 00 00 06 00 00 03 06 00 -T E8 04 -R 00 00 06 00 -T E8 04 CD D4 03 -R 00 00 06 00 00 03 06 00 -T EB 04 -R 00 00 06 00 -T EB 04 CD 57 04 0E 10 E5 -R 00 00 06 00 00 03 06 00 -T F1 04 -R 00 00 06 00 -T F1 04 D9 4B ED 78 D9 E6 7F FE 1B CA 2C 03 FE 13 -R 00 00 06 00 00 0C 06 00 -T FF 04 28 F0 7E CD 28 04 CD 4F 04 -R 00 00 06 00 00 06 06 00 00 09 06 00 -T 08 05 -R 00 00 06 00 -T 08 05 23 0D 20 E5 -R 00 00 06 00 -T 0C 05 -R 00 00 06 00 -T 0C 05 CD 4F 04 0E 10 E1 -R 00 00 06 00 00 03 06 00 -T 12 05 -R 00 00 06 00 -T 12 05 7E E6 60 7E 20 02 -R 00 00 06 00 -T 18 05 -R 00 00 06 00 -T 18 05 3E 2E -R 00 00 06 00 -T 1A 05 -R 00 00 06 00 -T 1A 05 CD C8 03 23 7A BC 20 05 7B BD CA 2C 03 -R 00 00 06 00 00 03 06 00 00 0D 06 00 -T 27 05 -R 00 00 06 00 -T 27 05 0D 20 E8 -R 00 00 06 00 -T 2A 05 -R 00 00 06 00 -T 2A 05 CD D4 03 C3 EB 04 -R 00 00 06 00 00 03 06 00 00 06 06 00 -T 30 05 -R 00 00 06 00 -T 30 05 CD D4 03 -R 00 00 06 00 00 03 06 00 -T 33 05 -R 00 00 06 00 -T 33 05 CD B4 03 -R 00 00 06 00 00 03 06 00 -T 36 05 -R 00 00 06 00 -T 36 05 FE 3A 20 47 1E 00 CD 0A 04 CD 8A 05 57 CD -R 00 00 06 00 00 09 06 00 00 0C 06 00 -T 44 05 0A 04 CD 8A 05 67 CD 0A 04 CD -R 00 00 06 00 00 02 06 00 00 05 06 00 00 09 06 00 -T 4E 05 8A 05 6F CD 0A 04 CD 8A 05 FE 01 20 0D CD -R 00 00 06 00 00 02 06 00 00 06 06 00 00 09 06 00 -T 5C 05 0A 04 CD 8A 05 7B A7 CA 96 05 18 19 -R 00 00 06 00 00 02 06 00 00 05 06 00 00 0A 06 00 -T 68 05 -R 00 00 06 00 -T 68 05 7A A7 28 0B CD 0A 04 CD 8A 05 77 23 15 18 -R 00 00 06 00 00 07 06 00 00 0A 06 00 -T 76 05 F1 -R 00 00 06 00 -T 77 05 -R 00 00 06 00 -T 77 05 CD 0A 04 CD 8A 05 7B A7 28 0F -R 00 00 06 00 00 03 06 00 00 06 06 00 -T 81 05 -R 00 00 06 00 -T 81 05 21 B5 0C CD 8A 04 C3 96 05 -R 00 00 06 00 00 03 06 00 00 06 06 00 00 09 06 00 -T 8A 05 -R 00 00 06 00 -T 8A 05 4F 7B 91 5F 79 C9 -R 00 00 06 00 -T 90 05 -R 00 00 06 00 -T 90 05 CD B4 03 C3 33 05 -R 00 00 06 00 00 03 06 00 00 06 06 00 -T 96 05 -R 00 00 06 00 -T 96 05 CD B4 03 C3 2C 03 -R 00 00 06 00 00 03 06 00 00 06 06 00 -T 9C 05 -R 00 00 06 00 -T 9C 05 0E 03 23 E5 CD DD 03 54 5D E1 D5 23 23 23 -R 00 00 06 00 00 07 06 00 -T AA 05 23 23 E5 CD DD 03 54 5D E1 D5 23 23 23 23 -R 00 00 06 00 00 06 06 00 -T B8 05 23 CD DD 03 E5 D1 C1 E1 E5 7D 2F 6F 7C 2F -R 00 00 06 00 00 04 06 00 -T C6 05 67 23 09 4D 44 E1 CD D2 05 C3 2C 03 -R 00 00 06 00 00 09 06 00 00 0C 06 00 -T D2 05 -R 00 00 06 00 -T D2 05 7E 12 23 13 0B 79 B0 C2 D2 05 C9 -R 00 00 06 00 00 0A 06 00 -T DD 05 -R 00 00 06 00 -T DD 05 0E 03 23 E5 CD DD 03 54 5D E1 D5 23 23 23 -R 00 00 06 00 00 07 06 00 -T EB 05 23 23 E5 CD DD 03 54 5D E1 D5 23 23 23 23 -R 00 00 06 00 00 06 06 00 -T F9 05 23 CD E9 03 4F C5 C1 D1 E1 71 -R 00 00 06 00 00 04 06 00 -T 03 06 -R 00 00 06 00 -T 03 06 71 23 7B 95 47 7A 94 B0 C2 03 06 C3 2C 03 -R 00 00 06 00 00 0B 06 00 00 0E 06 00 -T 11 06 -R 00 00 06 00 -T 11 06 C3 00 EA -R 00 00 06 00 -T 14 06 -R 00 00 06 00 -T 14 06 3E 80 D3 6B 3A 3A 07 D3 68 3E 00 D3 69 3E -R 00 00 06 00 00 07 06 00 -T 22 06 03 D3 6B 3E 03 D3 6C C9 -R 00 00 06 00 -T 2A 06 -R 00 00 06 00 -T 2A 06 5D 54 13 77 0B ED B0 C9 -R 00 00 06 00 -T 32 06 -R 00 00 06 00 -T 32 06 3E 0C 32 3A 07 CD 14 06 C9 -R 00 00 06 00 00 05 06 00 00 08 06 00 -T 3B 06 -R 00 00 06 00 -T 3B 06 3E 82 D3 63 C9 -R 00 00 06 00 -T 40 06 -R 00 00 06 00 -T 40 06 E5 -R 00 00 06 00 -T 41 06 -R 00 00 06 00 -T 41 06 CD 67 06 FE 00 28 F9 57 3E 4F D3 62 CD -R 00 00 06 00 00 03 06 00 -T 4E 06 B4 06 -R 00 00 06 00 00 02 06 00 -T 50 06 -R 00 00 06 00 -T 50 06 DB 61 FE 00 20 FA 7A 16 00 21 E7 0C -R 00 00 06 00 00 0C 06 00 -T 5C 06 -R 00 00 06 00 -T 5C 06 BE 28 05 23 14 C2 5C 06 -R 00 00 06 00 00 08 06 00 -T 64 06 -R 00 00 06 00 -T 64 06 7A E1 C9 -R 00 00 06 00 -T 67 06 -R 00 00 06 00 -T 67 06 0E 00 3E 41 D3 62 CD B4 06 DB 61 FE 00 20 -R 00 00 06 00 00 09 06 00 -T 75 06 34 0E 40 3E 42 D3 62 CD B4 06 DB 61 FE 00 -R 00 00 06 00 00 0A 06 00 -T 83 06 20 25 0E 80 3E 44 D3 62 CD B4 06 DB 61 FE -R 00 00 06 00 00 0B 06 00 -T 91 06 00 20 16 0E C0 3E 48 D3 62 CD B4 06 DB 61 -R 00 00 06 00 00 0C 06 00 -T 9F 06 FE 00 20 07 3E 40 D3 62 3E 00 C9 -R 00 00 06 00 -T AA 06 -R 00 00 06 00 -T AA 06 E6 3F B1 4F 3E 00 D3 62 79 C9 -R 00 00 06 00 -T B4 06 -R 00 00 06 00 -T B4 06 -R 00 00 06 00 -T B4 06 00 00 00 00 00 00 00 00 00 C9 -R 00 00 06 00 -T BE 06 -R 00 00 06 00 -T BE 06 E5 F5 C5 01 07 00 09 06 08 3E 40 D3 62 CD -R 00 00 06 00 -T CC 06 B4 06 3E F0 D3 60 3E 80 D3 62 CD B4 06 3E -R 00 00 06 00 00 02 06 00 00 0D 06 00 -T DA 06 40 D3 62 -R 00 00 06 00 -T DD 06 -R 00 00 06 00 -T DD 06 7E CD F8 06 D3 60 3E 00 D3 62 CD B4 06 3E -R 00 00 06 00 00 04 06 00 00 0D 06 00 -T EB 06 40 D3 62 CD B4 06 2B 10 E9 C1 F1 E1 C9 -R 00 00 06 00 00 06 06 00 -T F8 06 -R 00 00 06 00 -T F8 06 C5 E5 21 FF 0C 06 00 4F 09 7E E1 C1 C9 -R 00 00 06 00 00 05 06 00 -T 05 07 -R 00 00 06 00 -T 05 07 F5 C5 01 07 00 09 06 08 3E 40 D3 62 CD -R 00 00 06 00 -T 12 07 B4 06 3E F0 D3 60 3E 80 D3 62 CD B4 06 3E -R 00 00 06 00 00 02 06 00 00 0D 06 00 -T 20 07 40 D3 62 -R 00 00 06 00 -T 23 07 -R 00 00 06 00 -T 23 07 7E D3 60 3E 00 D3 62 CD B4 06 3E 40 D3 62 -R 00 00 06 00 00 0A 06 00 -T 31 07 CD B4 06 2B 10 EC C1 F1 C9 -R 00 00 06 00 00 03 06 00 -T 3A 07 -R 00 00 06 00 -T 3B 07 20 20 20 20 20 20 20 20 20 20 20 20 20 20 -R 00 00 06 00 -T 49 07 20 20 20 20 20 20 20 20 20 20 20 20 20 20 -R 00 00 06 00 -T 57 07 20 20 20 20 20 20 20 20 20 20 20 20 20 20 -R 00 00 06 00 -T 65 07 20 20 20 20 20 20 20 20 20 20 20 20 20 20 -R 00 00 06 00 -T 73 07 20 20 20 20 20 20 20 20 20 20 20 20 20 20 -R 00 00 06 00 -T 81 07 20 20 20 20 20 20 20 20 20 20 00 00 00 00 -R 00 00 06 00 -T 8F 07 00 00 00 00 01 -R 00 00 06 00 -T 94 07 -R 00 00 06 00 -T 94 07 -R 00 00 06 00 -T 94 09 -R 00 00 06 00 -T 94 09 0D 0A FF -R 00 00 06 00 -T 97 09 -R 00 00 06 00 -T 97 09 0D 0A 3E FF -R 00 00 06 00 -T 9B 09 -R 00 00 06 00 -T 9B 09 0D 0A 20 20 20 20 20 20 20 20 20 4E 4E 20 -R 00 00 06 00 -T A9 09 20 20 20 20 20 4E 4E 20 20 20 20 20 20 38 -R 00 00 06 00 -T B7 09 38 38 38 20 20 20 20 20 20 56 56 20 20 20 -R 00 00 06 00 -T C5 09 20 20 20 56 56 20 20 20 20 45 45 45 45 45 -R 00 00 06 00 -T D3 09 45 45 45 45 45 20 20 20 4D 4D 20 20 20 20 -R 00 00 06 00 -T E1 09 20 20 20 20 20 20 4D 4D 0D 0A 20 20 20 20 -R 00 00 06 00 -T EF 09 20 20 20 20 4E 4E 4E 4E 20 20 20 20 4E 4E -R 00 00 06 00 -T FD 09 20 20 20 20 38 38 20 20 20 20 38 38 20 20 -R 00 00 06 00 -T 0B 0A 20 20 56 56 20 20 20 20 20 20 56 56 20 20 -R 00 00 06 00 -T 19 0A 20 20 45 45 20 20 20 20 20 20 20 20 20 20 -R 00 00 06 00 -T 27 0A 20 4D 4D 4D 4D 20 20 20 20 20 20 4D 4D 4D -R 00 00 06 00 -T 35 0A 4D 0D 0A 20 20 20 20 20 20 20 4E 4E 20 20 -R 00 00 06 00 -T 43 0A 4E 4E 20 20 4E 4E 20 20 20 20 38 38 20 20 -R 00 00 06 00 -T 51 0A 20 20 38 38 20 20 20 20 56 56 20 20 20 20 -R 00 00 06 00 -T 5F 0A 20 20 56 56 20 20 20 20 45 45 20 20 20 20 -R 00 00 06 00 -T 6D 0A 20 20 20 20 20 20 20 4D 4D 20 20 4D 4D 20 -R 00 00 06 00 -T 7B 0A 20 4D 4D 20 20 4D 4D 0D 0A 20 20 20 20 20 -R 00 00 06 00 -T 89 0A 20 4E 4E 20 20 20 20 4E 4E 4E 4E 20 20 20 -R 00 00 06 00 -T 97 0A 20 38 38 20 20 20 20 38 38 20 20 20 20 56 -R 00 00 06 00 -T A5 0A 56 20 20 20 20 20 20 56 56 20 20 20 20 45 -R 00 00 06 00 -T B3 0A 45 20 20 20 20 20 20 20 20 20 20 20 4D 4D -R 00 00 06 00 -T C1 0A 20 20 20 20 4D 4D 20 20 20 20 4D 4D 0D 0A -R 00 00 06 00 -T CF 0A 20 20 20 20 20 4E 4E 20 20 20 20 20 20 4E -R 00 00 06 00 -T DD 0A 4E 20 20 20 20 20 20 38 38 38 38 20 20 20 -R 00 00 06 00 -T EB 0A 20 20 20 56 56 20 20 20 20 20 20 56 56 20 -R 00 00 06 00 -T F9 0A 20 20 20 45 45 45 45 45 45 45 20 20 20 20 -R 00 00 06 00 -T 07 0B 20 20 4D 4D 20 20 20 20 20 20 20 20 20 20 -R 00 00 06 00 -T 15 0B 4D 4D 0D 0A 20 20 20 20 4E 4E 20 20 20 20 -R 00 00 06 00 -T 23 0B 20 20 4E 4E 20 20 20 20 38 38 20 20 20 20 -R 00 00 06 00 -T 31 0B 38 38 20 20 20 20 20 56 56 20 20 20 20 56 -R 00 00 06 00 -T 3F 0B 56 20 20 20 20 20 45 45 20 20 20 20 20 20 -R 00 00 06 00 -T 4D 0B 20 20 20 20 20 4D 4D 20 20 20 20 20 20 20 -R 00 00 06 00 -T 5B 0B 20 20 20 4D 4D 0D 0A 20 20 20 4E 4E 20 20 -R 00 00 06 00 -T 69 0B 20 20 20 20 4E 4E 20 20 20 20 38 38 20 20 -R 00 00 06 00 -T 77 0B 20 20 38 38 20 20 20 20 20 20 56 56 20 20 -R 00 00 06 00 -T 85 0B 56 56 20 20 20 20 20 20 45 45 20 20 20 20 -R 00 00 06 00 -T 93 0B 20 20 20 20 20 20 20 4D 4D 20 20 20 20 20 -R 00 00 06 00 -T A1 0B 20 20 20 20 20 4D 4D 0D 0A 20 20 4E 4E 20 -R 00 00 06 00 -T AF 0B 20 20 20 20 20 4E 4E 20 20 20 20 38 38 20 -R 00 00 06 00 -T BD 0B 20 20 20 38 38 20 20 20 20 20 20 20 20 56 -R 00 00 06 00 -T CB 0B 56 56 20 20 20 20 20 20 20 45 45 20 20 20 -R 00 00 06 00 -T D9 0B 20 20 20 20 20 20 20 20 4D 4D 20 20 20 20 -R 00 00 06 00 -T E7 0B 20 20 20 20 20 20 4D 4D 0D 0A 20 4E 4E 20 -R 00 00 06 00 -T F5 0B 20 20 20 20 20 4E 4E 20 20 20 20 20 20 38 -R 00 00 06 00 -T 03 0C 38 38 38 20 20 20 20 20 20 20 20 20 20 20 -R 00 00 06 00 -T 11 0C 56 20 20 20 20 20 20 20 20 45 45 45 45 45 -R 00 00 06 00 -T 1F 0C 45 45 45 45 45 20 20 20 4D 4D 20 20 20 20 -R 00 00 06 00 -T 2D 0C 20 20 20 20 20 20 4D 4D 20 20 20 20 53 20 -R 00 00 06 00 -T 3B 0C 42 20 43 0D 0A 0D 0A 20 2A 2A 2A 2A 2A 2A -R 00 00 06 00 -T 49 0C 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A -R 00 00 06 00 -T 57 0C 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A -R 00 00 06 00 -T 65 0C 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A -R 00 00 06 00 -T 73 0C 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A -R 00 00 06 00 -T 81 0C 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A -R 00 00 06 00 -T 8F 0C 0D 0A 4D 4F 4E 49 54 4F 52 20 52 45 41 44 -R 00 00 06 00 -T 9D 0C 59 20 0D 0A FF -R 00 00 06 00 -T A2 0C -R 00 00 06 00 -T A2 0C 0D 0A 55 4E 4B 4E 4F 57 4E 20 43 4F 4D 4D -R 00 00 06 00 -T B0 0C 41 4E 44 2E FF -R 00 00 06 00 -T B5 0C -R 00 00 06 00 -T B5 0C 0D 0A 43 48 45 43 4B 53 55 4D 20 45 52 52 -R 00 00 06 00 -T C3 0C 4F 52 2E FF -R 00 00 06 00 -T C7 0C -R 00 00 06 00 -T C7 0C 84 EE BB 80 BB EE CB 84 -R 00 00 06 00 -T CF 0C -R 00 00 06 00 -T CF 0C 00 00 00 00 8C BD BD FE -R 00 00 06 00 -T D7 0C -R 00 00 06 00 -T D7 0C 00 00 80 80 94 8C 9D EE -R 00 00 06 00 -T DF 0C -R 00 00 06 00 -T DF 0C 80 80 80 80 80 CB CF D7 -R 00 00 06 00 -T E7 0C -R 00 00 06 00 -T E7 0C 41 02 42 82 04 44 84 08 48 88 10 50 90 20 -R 00 00 06 00 -T F5 0C 60 A0 01 81 C1 C2 C4 C8 D0 E0 -R 00 00 06 00 -T FF 0C -R 00 00 06 00 -T FF 0C FB B0 ED F5 B6 D7 DF F0 FF F7 FE 9F CB BD -R 00 00 06 00 -T 0D 0D CF CE 80 84 00 EE 9D -R 00 00 06 00 -T 14 0D -R 00 00 06 00 diff --git a/doug/src/dbgmon.s b/doug/src/dbgmon.s deleted file mode 100755 index cc6fb426..00000000 --- a/doug/src/dbgmon.s +++ /dev/null @@ -1,1764 +0,0 @@ - .title dbgmon.s derived from dbgmon.asm - .sbttl Ported by Douglas Goodall - - .module dbgmon - .optsdcc -mz80 - -;-------------------------------------------------------- -; Public variables in this module -;-------------------------------------------------------- - .globl _dbgmon -;-------------------------------------------------------- -; special function registers -;-------------------------------------------------------- -;-------------------------------------------------------- -; ram data -;-------------------------------------------------------- - .area _DATA -;-------------------------------------------------------- -; overlayable items in ram -;-------------------------------------------------------- - .area _OVERLAY -;-------------------------------------------------------- -; external initialized ram data -;-------------------------------------------------------- -;-------------------------------------------------------- -; global & static initialisations -;-------------------------------------------------------- - .area _HOME - .area _GSINIT - .area _GSFINAL - .area _GSINIT -;-------------------------------------------------------- -; Home -;-------------------------------------------------------- - .area _HOME - .area _HOME -;-------------------------------------------------------- -; code -;-------------------------------------------------------- - .area _DBGMON -_dbgmon_start:: -_dbgmon: - - -;___ROM_MONITOR_PROGRAM_____________________________________________________________________________________________________________ -; -; ORIGINAL CODE BY: ANDREW LYNCH (LYNCHAJ@YAHOO COM) 13 FEB 2007 -; -; MODIFIED BY : DAN WERNER 03 09.2009 -; -;__REFERENCES________________________________________________________________________________________________________________________ -; THOMAS SCHERRER BASIC HAR.DWARE TEST ASSEMBLER SOURCES FROM THE Z80 INFO PAGE -; INCLUDING ORIGINAL SCHEMATIC CONCEPT -; HTTP://Z80 INFO/Z80SOURC.TXT -; CODE SAMPLES FROM BRUCE JONES PUBLIC DOMAIN ROM MONITOR FOR THE SBC-200C -; HTTP://WWW RETROTECHNOLOGY.COM/HERBS_STUFF/SD_BRUCE_CODE.ZIP -; INSPIRATION FROM JOEL OWENS "Z-80 SPACE-TIME PRODUCTIONS SINGLE BOARD COMPUTER" -; HTTP://WWW JOELOWENS.ORG/Z80/Z80INDEX.HTML -; GREAT HELP AND TECHNICAL ADVICE FROM ALLISON AT ALPACA_DESIGNERS -; HTTP://GROUPS YAHOO.COM/GROUP/ALPACA_DESIGNERS -; INTEL SDK-85 ROM DEBUG MONITOR -; -;__HARDWARE_INTERFACES________________________________________________________________________________________________________________ -; -; PIO 82C55 I/O IS DECODED TO PORT 60-67 -; -PORTA = 0x60 -PORTB = 0x61 -PORTC = 0x62 -PIOCONT = 0x63 -; -; UART 16C450 SERIAL IS DECODED TO 68-6F -; -UART0 = 0x68 ; DATA IN/OUT -UART1 = 0x69 ; CHECK RX -UART2 = 0x6A ; INTERRUPTS -UART3 = 0x6B ; LINE CONTROL -UART4 = 0x6C ; MODEM CONTROL -UART5 = 0x6D ; LINE STATUS -UART6 = 0x6E ; MODEM STATUS -UART7 = 0x6F ; SCRATCH REG. -; -; MEMORY PAGE CONFIGURATION LATCH IS DECODED TO 78 -; -MPCL = 0x78 ; CONTROL PORT, SHOULD ONLY BE CHANGED WHILE -; IN UPPER MEMORY PAGE 08000h-$FFFF OR LIKELY -MPCL_RAM = 0x78 ; BASE IO ADDRESS OF RAM MEMORY PAGER CONFIGURATION LATCH -MPCL_ROM = 0x7C ; BASE IO ADDRESS OF ROM MEMORY PAGER CONFIGURATION LATCH -; LOSS OF CPU MEMORY CONTEXT -; -; MEMORY PAGE CONFIGURATION LATCH CONTROL PORT ( IO_Y3 ) INFORMATION -; -; 7 6 5 4 3 2 1 0 ONLY APPLICABLE TO THE LOWER MEMORY PAGE 00000h-$7FFF -; ^ ^ ^ ^ ^ ^ ^ ^ -; : : : : : : : :--0 = A15 RAM/ROM ADDRESS LINE DEFAULT IS 0 -; : : : : : : :----0 = A16 RAM/ROM ADDRESS LINE DEFAULT IS 0 -; : : : : : :------0 = A17 RAM/ROM ADDRESS LINE DEFAULT IS 0 -; : : : : :--------0 = A18 RAM/ROM ADDRESS LINE DEFAULT IS 0 -; : : : :-----------0 = A19 ROM ONLY ADDRESS LINE DEFAULT IS 0 -; : : :-------------0 = -; : :---------------0 = -; :-----------------0 = ROM SELECT (0=ROM, 1=RAM) DEFAULT IS 0 -; -; -;IDE REGISTER IO PORT ; FUNCTION -IDELO = 0x020 ; DATA PORT (LOW BYTE) -IDEERR = 0x021 ; READ: ERROR REGISTER; WRITE: PRECOMP -IDESECTC = 0x022 ; SECTOR COUNT -IDESECTN = 0x023 ; SECTOR NUMBER -IDECYLLO = 0x024 ; CYLINDER LOW -IDECYLHI = 0x025 ; CYLINDER HIGH -IDEHEAD = 0x026 ; DRIVE/HEAD -IDESTTS = 0x027 ; READ: STATUS; WRITE: COMMAND -IDEHI = 0x028 ; DATA PORT (HIGH BYTE) -IDECTRL = 0x02E ; READ: ALTERNATIVE STATUS; WRITE; DEVICE CONTROL -IDEADDR = 0x02F ; DRIVE ADDRESS (READ ONLY) - -; -; -;__CONSTANTS_________________________________________________________________________________________________________________________ -; -RAMTOP = 0x0FFFF ; HIGHEST ADDRESSABLE MEMORY LOCATION -STACKSTART = 0x0CFFF ; START OF STACK -RAMBOTTOM = 0x08000 ; START OF FIXED UPPER 32K PAGE OF 512KB X 8 RAM 8000H-FFFFH -MONSTARTCOLD = 0x08000 ; COLD START MONITOR IN HIGH RAM -ENDT = 0x0FF ; MARK END OF TEXT -CR = 0x0D ; ASCII CARRIAGE RETURN CHARACTER -LF = 0x0A ; ASCII LINE FEED CHARACTER -ESC = 0x1B ; ASCII ESCAPE CHARACTER -BS = 0x08 ; ASCII BACKSPACE CHARACTER - -ASCIIA = 0x41 -ASCIIB = 0x42 -ASCIIC = 0x43 -ASCIID = 0x44 -ASCIIE = 0x45 -ASCIIF = 0x46 -ASCIIG = 0x47 -ASCIIH = 0x48 -ASCIII = 0x49 -ASCIIJ = 0x4A -ASCIIK = 0x4B -ASCIIL = 0x4C -ASCIIM = 0x4D -ASCIIN = 0x4E -ASCIIO = 0x4F -ASCIIP = 0x50 -ASCIIQ = 0x51 -ASCIIR = 0x52 -ASCIIS = 0x53 -ASCIIT = 0x54 -ASCIIU = 0x55 -ASCIIV = 0x56 -ASCIIW = 0x57 -ASCIIX = 0x58 -ASCIIY = 0x59 -ASCIIZ = 0x5A - -; -; -; -;__MAIN_PROGRAM_____________________________________________________________________________________________________________________ -; -; ORG 00100h ; FOR DEBUG IN CP/M (AS .COM) - -;dwg; .ORG 8000H ; NORMAL OP - - LD SP,#STACKSTART ; SET THE STACK POINTER TO STACKSTART - CALL INITIALIZE ; INITIALIZE SYSTEM - - - -;__FRONT_PANEL_STARTUP___________________________________________________________________________________________________________ -; -; START UP THE SYSTEM WITH THE FRONT PANEL INTERFACE -; -;________________________________________________________________________________________________________________________________ -; - CALL MTERM_INIT ; INIT 8255 FOR MTERM - LD HL,#CPUUP ; SET POINTER TO DATA BUFFER - CALL SEGDISPLAY ; DISPLAY - - - -FRONTPANELLOOP: - CALL KB_GET ; GET KEY FROM KB - - CP #0x10 ; IS PORT READ? - JP Z,DOPORTREAD ; YES, JUMP - CP #0x11 ; IS PORT WRITE? - JP Z,DOPORTWRITE ; YES, JUMP - CP #0x14 ; IS DEPOSIT? - JP Z,DODEPOSIT ; YES, JUMP - CP #0x15 ; IS EXAMINE? - JP Z,DOEXAMINE ; YES, JUMP - CP #0x16 ; IS GO? - JP Z,DOGO ; YES, JUMP - CP #0x17 ; IS BO? - JP Z,DOBOOT ; YES, JUMP - - JR FRONTPANELLOOP ; LOOP -EXIT: - RET - - -;__DOBOOT________________________________________________________________________________________________________________________ -; -; PERFORM BOOT FRONT PANEL ACTION -;________________________________________________________________________________________________________________________________ -; -DOBOOT: - LD A,#0 ; LOAD VALUE TO SWITCH OUT ROM - OUT (MPCL_ROM),A ; SWITCH OUT ROM, BRING IN LOWER 32K RAM PAGE - ; - ; - OUT (MPCL_RAM),A ; - JP 0 ; GO TO CP/M - - -;__DOPORTREAD____________________________________________________________________________________________________________________ -; -; PERFORM PORT READ FRONT PANEL ACTION -;________________________________________________________________________________________________________________________________ -; -DOPORTREAD: - CALL GETPORT ; GET PORT INTO A -PORTREADLOOP: - LD C,A ; STORE PORT IN "C" - SRL A ; ROTATE HIGH NIB TO LOW - SRL A ; - SRL A ; - SRL A ; - LD (DISPLAYBUF+5),A ; SHOW HIGH NIB IN DISP 5 - LD A,C ; RESTORE PORT VALUE INTO "A" - AND #0x0F ; CLEAR HIGH NIB, LEAVING LOW - LD (DISPLAYBUF+4),A ; SHOW LOW NIB IN DISP 4 - IN A,(C) ; GET PORT VALUE FROM PORT IN "C" - LD C,A ; STORE VALUE IN "C" - SRL A ; ROTATE HIGH NIB TO LOW - SRL A ; - SRL A ; - SRL A ; - LD (DISPLAYBUF+1),A ; SHOW HIGH NIB IN DISP 1 - LD A,C ; RESTORE VALUE TO "A" - AND #0x0F ; CLEAR HIGH NIB, LEAVING LOW - LD (DISPLAYBUF),A ; DISPLAY LOW NIB IN DISP 0 - LD A,#0x10 ; CLEAR OTHER DISPLAYS - LD (DISPLAYBUF+2),A ; - LD (DISPLAYBUF+3),A ; - LD A,#0x13 ; "P" - LD (DISPLAYBUF+7),A ; STORE IN DISP 7 - LD A,#0x14 ; "O" - LD (DISPLAYBUF+6),A ; STORE IN DISP 6 - LD HL,#DISPLAYBUF ; SET POINTER TO DISPLAY BUFFER - CALL HEXDISPLAY ; DISPLAY BUFFER CONTENTS -PORTREADGETKEY: - CALL KB_GET ; GET KEY FROM KB - CP #0x12 ; [CL] PRESSED, EXIT - JP Z,PORTREADEXIT ; - CP #0x10 ; [PR] PRESSED, PROMPT FOR NEW PORT - JR Z,DOPORTREAD ; - JR PORTREADGETKEY ; NO VALID KEY, LOOP -PORTREADEXIT: - LD HL,#CPUUP ; SET POINTER TO DATA BUFFER - CALL SEGDISPLAY ; DISPLAY - JP FRONTPANELLOOP ; - -;__DOPORTWRITE____________________________________________________________________________________________________________________ -; -; PERFORM PORT WRITE FRONT PANEL ACTION -;________________________________________________________________________________________________________________________________ -; -DOPORTWRITE: - CALL GETPORT ; GET PORT INTO A -PORTWRITELOOP: - LD C,A ; STORE PORT IN "C" - SRL A ; ROTATE HIGH NIB INTO LOW - SRL A ; - SRL A ; - SRL A ; - LD (DISPLAYBUF+5),A ; DISPLAY HIGH NIB IN DISPLAY 5 - LD A,C ; RESTORE PORT VALUE INTO "A" - AND #0x0F ; CLEAR OUT HIGH NIB - LD (DISPLAYBUF+4),A ; DISPLAY LOW NIB IN DISPLAY 4 - LD A,#0x10 ; CLEAR OUT DISPLAYS 2 AND 3 - LD (DISPLAYBUF+2),A ; - LD (DISPLAYBUF+3),A ; - LD A,#0x13 ; DISPLAY "P" IN DISP 7 - LD (DISPLAYBUF+7),A ; - LD A,#0x14 ; DISPLAY "O" IN DISP 6 - LD (DISPLAYBUF+6),A ; - LD HL,#DISPLAYBUF ; POINT TO DISPLAY BUFFER - CALL GETVALUE ; INPUT A BYTE VALUE, RETURN IN "A" - OUT (C),A ; OUTPUT VALUE TO PORT STORED IN "C" - LD HL,#CPUUP ; SET POINTER TO DATA BUFFER - CALL SEGDISPLAY ; DISPLAY - JP FRONTPANELLOOP ; - - -;__DOGO__________________________________________________________________________________________________________________________ -; -; PERFORM GO FRONT PANEL ACTION -;________________________________________________________________________________________________________________________________ -; -DOGO: - CALL GETADDR ; GET ADDRESS INTO HL - JP (HL) ; GO THERE! - - - -;__DODEPOSIT________________________________________________________________________________________________________________________ -; -; PERFORM DEPOSIT FRONT PANEL ACTION -;________________________________________________________________________________________________________________________________ -; -DODEPOSIT: - CALL GETADDR ; GET ADDRESS INTO HL - PUSH HL -DEPOSITLOOP: - LD A,H ; - SRL A ; - SRL A ; - SRL A ; - SRL A ; - LD (DISPLAYBUF+7),A ; - LD A,H ; - AND #0x0F ; - LD (DISPLAYBUF+6),A ; - LD A,L ; - SRL A ; - SRL A ; - SRL A ; - SRL A ; - LD (DISPLAYBUF+5),A ; - LD A,L ; - AND #0x0F ; - LD (DISPLAYBUF+4),A ; - LD A,#0x10 ; - LD (DISPLAYBUF+3),A ; - LD HL,#DISPLAYBUF ; - CALL GETVALUE ; - POP HL ; - LD (HL),A ; -DEPOSITGETKEY: - CALL KB_GET ; GET KEY FROM KB - CP #0x12 ; [CL] PRESSED, EXIT - JP Z,DEPOSITEXIT ; - CP #0x13 ; [EN] PRESSED, INC ADDRESS AND LOOP - JR Z,DEPOSITFW ; - CP #0x14 ; [DE] PRESSED, PROMPT FOR NEW ADDRESS - JR Z,DODEPOSIT ; - JR DEPOSITGETKEY ; NO VALID KEY, LOOP -DEPOSITFW: - INC HL ; - PUSH HL ; STORE HL - JR DEPOSITLOOP ; -DEPOSITEXIT: - LD HL,#CPUUP ; SET POINTER TO DATA BUFFER - CALL SEGDISPLAY ; DISPLAY - JP FRONTPANELLOOP ; - - - - -;__DOEXAMINE________________________________________________________________________________________________________________________ -; -; PERFORM EXAMINE FRONT PANEL ACTION -;________________________________________________________________________________________________________________________________ -; -DOEXAMINE: - CALL GETADDR ; GET ADDRESS INTO HL - PUSH HL ; STORE HL -EXAMINELOOP: - LD A,H ; MOVE HIGH BYTE IN "A" - SRL A ; SHOW HIGH NIBBLE IN DISP 7 - SRL A ; - SRL A ; - SRL A ; - LD (DISPLAYBUF+7),A ; - LD A,H ; RESTORE HIGH BYTE - AND #0x0F ; CLEAR HIGH NIBBLE - LD (DISPLAYBUF+6),A ; DISPLAY LOW NIBBLE IN DISP 6 - LD A,L ; PUT LOW BYTE IN "A" - SRL A ; SHOW HIGH NIBBLE IN DISP 5 - SRL A ; - SRL A ; - SRL A ; - LD (DISPLAYBUF+5),A ; - LD A,L ; RESTORE LOW BYTE IN "A" - AND #0x0F ; CLEAR OUT HIGH NIBBLE - LD (DISPLAYBUF+4),A ; DISPLAY LOW NIBBLE IN DISP 4 - LD A,#0x10 ; CLEAR OUT DISP 3 - LD (DISPLAYBUF+3),A ; - LD A,(HL) ; GET VALUE FROM ADDRESS IN HL - SRL A ; DISPLAY HIGH NIB IN DISPLAY 1 - SRL A ; - SRL A ; - SRL A ; - LD (DISPLAYBUF+1),A ; - LD A,(HL) ; GET VALUE FROM ADDRESS IN HL - AND #0x0F ; CLEAR OUT HIGH NIBBLE - LD (DISPLAYBUF),A ; DISPLAY LOW NIBBLE IN DISPLAY 0 - LD HL,#DISPLAYBUF ; POINT TO DISPLAY BUFFER - CALL HEXDISPLAY ; DISPLAY BUFFER ON DISPLAYS - POP HL ; RESTORE HL -EXAMINEGETKEY: - CALL KB_GET ; GET KEY FROM KB - CP #0x12 ; [CL] PRESSED, EXIT - JP Z,EXAMINEEXIT ; - CP #0x13 ; [EN] PRESSED, INC ADDRESS AND LOOP - JR Z,EXAMINEFW ; - CP #0x15 ; [DE] PRESSED, PROMPT FOR NEW ADDRESS - JR Z,DOEXAMINE ; - JR EXAMINEGETKEY ; NO VALID KEY, LOOP -EXAMINEFW: - INC HL ; HL++ - PUSH HL ; STORE HL - JR EXAMINELOOP ; -EXAMINEEXIT: - LD HL,#CPUUP ; SET POINTER TO DATA BUFFER - CALL SEGDISPLAY ; DISPLAY - JP FRONTPANELLOOP ; - - -;__GETADDR_______________________________________________________________________________________________________________________ -; -; GET ADDRESS FROM FRONT PANEL -;________________________________________________________________________________________________________________________________ -; -GETADDR: - PUSH BC ; STORE BC - JR GETADDRCLEAR ; -GETADDR1: - LD HL,#ADDR ; DISPLAY PROMPT - CALL SEGDISPLAY ; -GETADDRLOOP: - CALL KB_GET ; - CP #0x10 ; - JP M,GETADDRNUM ; NUMBER PRESSED, STORE IT - CP #0x13 ; EN PRESSED, DONE - JR Z,GETADDRDONE ; - CP #0x12 ; CLEAR PRESSED, CLEAR - JR Z,GETADDRCLEAR ; - JR GETADDRLOOP ; INVALID KEY, LOOP -GETADDRDONE: - LD HL,#0 ; HL=0 - LD A,(DISPLAYBUF+1) ; GET DIGIT IN DISPLAY 1 - SLA A ; ROTATE IT TO HIGH NIBBLE - SLA A ; - SLA A ; - SLA A ; - LD C,A ; STORE IT IN "C" - LD A,(DISPLAYBUF) ; GET DIGIT IN DISPLAY 0 - AND #0x0F ; CLEAR HIGH NIBBLE - OR C ; ADD IN NIBBLE STORED IN C - LD L,A ; STORE IT IN LOW BYTE OF ADDRESS POINTER - LD A,(DISPLAYBUF+3) ; GET DIGIT IN DISPLAY 3 - SLA A ; ROTATE IT TO HIGH NIBBLE - SLA A ; - SLA A ; - SLA A ; - LD C,A ; STORE IT IN "C" - LD A,(DISPLAYBUF+2) ; GET DIGIT IN DISPLAY 2 - AND #0x0F ; CLEAR HIGH NIBBLE - OR C ; ADD IN NIBBLE STORED IN "C" - LD H,A ; STORE BYTE IN HIGH BYTE OF ADDRESS POINTER - LD A,#0x10 ; CLEAR OUT DISPLAYS 0,1,2 & 3 - LD (DISPLAYBUF),A ; - LD (DISPLAYBUF+1),A ; - LD (DISPLAYBUF+2),A ; - LD (DISPLAYBUF+3),A ; - POP BC ; RESTORE BC - RET -GETADDRNUM: - LD C,A ; - LD A,(DISPLAYBUF+2) ; SHIFT BYTES IN DISPLAY BUF TO THE LEFT - LD (DISPLAYBUF+3),A ; - LD A,(DISPLAYBUF+1) ; - LD (DISPLAYBUF+2),A ; - LD A,(DISPLAYBUF) ; - LD (DISPLAYBUF+1),A ; - LD A,C ; DISPLAY KEYSTROKE IN RIGHT MOST DISPLAY (0) - LD (DISPLAYBUF+0),A ; - JR GETADDRDISP ; -GETADDRCLEAR: - LD A,#0x12 ; CLEAR OUT DISPLAYS 0,1,2 & 3 - LD (DISPLAYBUF),A ; - LD (DISPLAYBUF+1),A ; - LD (DISPLAYBUF+2),A ; - LD (DISPLAYBUF+3),A ; -GETADDRDISP: - LD A,(DISPLAYBUF) ; ENCODE DIGITS IN DISPLAY BUFFER TO DISPLAY - CALL DECODEDISPLAY ; - LD (ADDR),A ; - LD A,(DISPLAYBUF+1) ; - CALL DECODEDISPLAY ; - LD (ADDR+1),A ; - LD A,(DISPLAYBUF+2) ; - CALL DECODEDISPLAY ; - LD (ADDR+2),A ; - LD A,(DISPLAYBUF+3) ; - CALL DECODEDISPLAY ; - LD (ADDR+3),A ; - JP GETADDR1 ; - - - -;__DSPSECTOR_______________________________________________________________________________________________________________________ -; -; DISPLAY SECTOR IN HL ON FRONT PANEL -;________________________________________________________________________________________________________________________________ -; -DSPSECTOR: - PUSH BC ; STORE BC - PUSH HL ; STORE HL - LD A,H ; DISPLAY HIGH BYTE, HIGH NIBBLE - SRL A ; - SRL A ; - SRL A ; - SRL A ; - AND #0x0F ; - CALL DECODEDISPLAY ; - LD (SEC+3),A ; - LD A,H ; DISPLAY HIGH BYTE, LOW NIBBLE - AND #0x0F ; - CALL DECODEDISPLAY ; - LD (SEC+2),A ; - LD A,L ; DISPLAY LOW BYTE, HIGH NIBBLE - AND #0x0F0 ; - SRL A ; - SRL A ; - SRL A ; - SRL A ; - AND #0x0F ; - CALL DECODEDISPLAY ; - LD (SEC+1),A ; DISPLAY LOW BYTE, LOW NIBBLE - LD A,L ; - AND #0x0F ; - CALL DECODEDISPLAY ; - LD (SEC),A ; - LD HL,#SEC ; DISPLAY PROMPT - CALL SEGDISPLAY ; - POP HL ; RESTORE HL - POP BC ; RESTORE BC - RET - - - -;__GETPORT_______________________________________________________________________________________________________________________ -; -; GET PORT FROM FRONT PANEL -;________________________________________________________________________________________________________________________________ -; -GETPORT: - PUSH BC ; STORE BC - JR GETPORTCLEAR ; -GETPORT1: - LD HL,#PORT ; DISPLAY PROMPT - CALL SEGDISPLAY ; -GETPORTLOOP: - CALL KB_GET ; - CP #0x10 ; - JP M,GETPORTNUM ; NUMBER PRESSED, STORE IT - CP #0x13 ; EN PRESSED, DONE - JR Z,GETPORTDONE ; - CP #0x12 ; CLEAR PRESSED, CLEAR - JR Z,GETPORTCLEAR ; - JR GETPORTLOOP ; INVALID KEY, LOOP -GETPORTDONE: - LD A,(DISPLAYBUF+1) ; - SLA A ; - SLA A ; - SLA A ; - SLA A ; - LD C,A ; - LD A,(DISPLAYBUF) ; - AND #0x0F ; - OR C ; - LD C,A ; - LD A,#0x10 ; - LD (DISPLAYBUF),A ; - LD (DISPLAYBUF+1),A ; - LD A,C ; - POP BC ; RESTORE BC - RET -GETPORTNUM: - LD C,A ; - LD A,(DISPLAYBUF) ; - LD (DISPLAYBUF+1),A ; - LD A,C ; - LD (DISPLAYBUF+0),A ; - JR GETPORTDISP ; -GETPORTCLEAR: - LD A,#0x12 ; - LD (DISPLAYBUF),A ; - LD (DISPLAYBUF+1),A ; -GETPORTDISP: - LD A,(DISPLAYBUF) ; - CALL DECODEDISPLAY ; - LD (PORT),A ; - LD A,(DISPLAYBUF+1) ; - CALL DECODEDISPLAY ; - LD (PORT+1),A ; - JP GETPORT1 ; - - -;__GETVALUE______________________________________________________________________________________________________________________ -; -; GET VALUE FROM FRONT PANEL -;________________________________________________________________________________________________________________________________ -; -GETVALUE: - PUSH BC ; STORE BC - JR GETVALUECLEAR ; -GETVALUE1: - CALL HEXDISPLAY ; - -GETVALUELOOP: - CALL KB_GET ; - CP #0x10 ; - JP M,GETVALUENUM ; NUMBER PRESSED, STORE IT - CP #0x13 ; EN PRESSED, DONE - JR Z,GETVALUEDONE ; - CP #0x12 ; CLEAR PRESSED, CLEAR - JR Z,GETVALUECLEAR ; - JR GETVALUELOOP ; INVALID KEY, LOOP -GETVALUEDONE: - LD A,(DISPLAYBUF+1) ; - SLA A ; - SLA A ; - SLA A ; - SLA A ; - LD C,A ; - LD A,(DISPLAYBUF) ; - AND #0x0F ; - OR C ; - LD C,A ; - LD A,#0x10 ; - LD (DISPLAYBUF),A ; - LD (DISPLAYBUF+1),A ; - LD A,C ; - POP BC ; RESTORE BC - RET -GETVALUENUM: - LD C,A ; - LD A,(DISPLAYBUF) ; - LD (DISPLAYBUF+1),A ; - LD A,C ; - LD (DISPLAYBUF+0),A ; - JR GETVALUE1 ; -GETVALUECLEAR: - LD A,#0x12 ; - LD (DISPLAYBUF),A ; - LD (DISPLAYBUF+1),A ; - JP GETVALUE1 ; - - -;__MONSTARTWARM___________________________________________________________________________________________________________________ -; -; SERIAL MONITOR STARTUP -;________________________________________________________________________________________________________________________________ -; - -MONSTARTWARM: ; CALL HERE FOR SERIAL MONITOR WARM START - LD SP,#STACKSTART ; SET THE STACK POINTER TO STACKSTART - CALL INITIALIZE ; INITIALIZE SYSTEM - - XOR A ;ZERO OUT ACCUMULATOR (ADDED) - PUSH HL ;PROTECT HL FROM OVERWRITE - LD HL,#TXT_READY ;POINT AT TEXT - CALL MSG ;SHOW WE'RE HERE - POP HL ;PROTECT HL FROM OVERWRITE - -; -;__SERIAL_MONITOR_COMMANDS_________________________________________________________________________________________________________ -; -; B XX BOOT CPM FROM DRIVE XX -; D XXXXH YYYYH DUMP MEMORY FROM XXXX TO YYYY -; F XXXXH YYYYH ZZH FILL MEMORY FROM XXXX TO YYYY WITH ZZ -; H LOAD INTEL HEX FORMAT DATA -; I INPUT FROM PORT AND SHOW HEX DATA -; K ECHO KEYBOARD INPUT -; M XXXXH YYYYH ZZZZH MOVE MEMORY BLOCK XXXX TO YYYY TO ZZZZ -; O OUTPUT TO PORT HEX DATA -; P XXXXH YYH PROGRAM RAM FROM XXXXH WITH VALUE IN YYH, WILL PROMPT FOR NEXT LINES FOLLOWING UNTIL CR -; R RUN A PROGRAM FROM CURRENT LOCATION - - - -;__COMMAND_PARSE_________________________________________________________________________________________________________________ -; -; PROMPT USER FOR COMMANDS, THEN PARSE THEM -;________________________________________________________________________________________________________________________________ -; - -SERIALCMDLOOP: - CALL CRLFA ; CR,LF,> - LD HL,#KEYBUF ; SET POINTER TO KEYBUF AREA - CALL GETLN ; GET A LINE OF INPUT FROM THE USER - LD HL,#KEYBUF ; RESET POINTER TO START OF KEYBUF - LD A,(HL) ; LOAD FIRST CHAR INTO A (THIS SHOULD BE THE COMMAND) - INC HL ; INC POINTER - - CP #ASCIIB ; IS IT "B" (Y/N) - JP Z,DOBOOT ; IF YES DO BOOT - CP #ASCIIR ; IS IT "R" (Y/N) - JP Z,RUN ; IF YES GO RUN ROUTINE - CP #ASCIIP ; IS IT "P" (Y/N) - JP Z,PROGRM ; IF YES GO PROGRAM ROUTINE - CP #ASCIIO ; IS IT AN "O" (Y/N) - JP Z,POUT ; PORT OUTPUT - CP #ASCIIH ; IS IT A "H" (Y/N) - JP Z,HXLOAD ; INTEL HEX FORMAT LOAD DATA - CP #ASCIII ; IS IT AN "I" (Y/N) - JP Z,PIN ; PORT INPUT - CP #ASCIID ; IS IT A "D" (Y/N) - JP Z,DUMP ; DUMP MEMORY - CP #ASCIIK - JP Z,KLOP ; LOOP ON KEYBOARD - CP #ASCIIM ; IS IT A "M" (Y/N) - JP Z,MOVE ; MOVE MEMORY COMMAND - CP #ASCIIF ; IS IT A "F" (Y/N) - JP Z,FILL ; FILL MEMORY COMMAND - LD HL,#TXT_COMMAND ; POINT AT ERROR TEXT - CALL MSG ; PRINT COMMAND LABEL - - JR SERIALCMDLOOP - - - - - -;__KLOP__________________________________________________________________________________________________________________________ -; -; READ FROM THE SERIAL PORT AND ECHO, MONITOR COMMAND "K" -;________________________________________________________________________________________________________________________________ -; -KLOP: - CALL KIN ; GET A KEY - CALL COUT ; OUTPUT KEY TO SCREEN - CP #ESC ; IS ? - JR NZ,KLOP ; NO, LOOP - JP SERIALCMDLOOP ; - -;__GETLN_________________________________________________________________________________________________________________________ -; -; READ A LINE(80) OF TEXT FROM THE SERIAL PORT, HANDLE , TERM ON -; EXIT IF TOO MANY CHARS STORE RESULT IN HL. CHAR COUNT IN C. -;________________________________________________________________________________________________________________________________ -; -GETLN: - LD C,#0 ; ZERO CHAR COUNTER - PUSH DE ; STORE DE -GETLNLOP: - CALL KIN ; GET A KEY - CALL COUT ; OUTPUT KEY TO SCREEN - CP #CR ; IS ? - JR Z,GETLNDONE ; YES, EXIT - CP #BS ; IS ? - JR NZ,GETLNSTORE ; NO, STORE CHAR - LD A,C ; A=C - CP #0 ; - JR Z,GETLNLOP ; NOTHING TO BACKSPACE, IGNORE & GET NEXT KEY - DEC HL ; PERFORM BACKSPACE - DEC C ; LOWER CHAR COUNTER - LD A,#0 ; - LD (HL),A ; STORE NULL IN BUFFER - LD A,#0x20 ; BLANK OUT CHAR ON TERM - CALL COUT ; - LD A,#BS ; - CALL COUT ; - JR GETLNLOP ; GET NEXT KEY -GETLNSTORE: - LD (HL),A ; STORE CHAR IN BUFFER - INC HL ; INC POINTER - INC C ; INC CHAR COUNTER - LD A,C ; A=C - CP #0x4D ; OUT OF BUFFER SPACE? - JR NZ,GETLNLOP ; NOPE, GET NEXT CHAR -GETLNDONE: - LD (HL),#0 ; STORE NULL IN BUFFER - POP DE ; RESTORE DE - RET ; - - -;__KIN___________________________________________________________________________________________________________________________ -; -; READ FROM THE SERIAL PORT AND ECHO & CONVERT INPUT TO UCASE -;________________________________________________________________________________________________________________________________ -; -KIN: - IN A,(UART5) ; READ LINE STATUS REGISTER - BIT 0,A ; TEST IF DATA IN RECEIVE BUFFER - JP Z,KIN ; LOOP UNTIL DATA IS READY - IN A,(UART0) ; THEN READ THE CHAR FROM THE UART - AND #0x7F ; STRIP HI BIT - CP #ASCIIA ; KEEP NUMBERS, CONTROLS - RET C ; AND UPPER CASE - CP #0x7B ; SEE IF NOT LOWER CASE - RET NC ; - AND #0x5F ; MAKE UPPER CASE - RET - - -;__COUT__________________________________________________________________________________________________________________________ -; -; WRITE THE VALUE IN "A" TO THE SERIAL PORT -;________________________________________________________________________________________________________________________________ -; -COUT: - PUSH AF ; STORE AF -TX_BUSYLP: - IN A,(UART5) ; READ LINE STATUS REGISTER - BIT 5,A ; TEST IF UART IS READY TO SEND - JP Z,TX_BUSYLP ; IF NOT REPEAT - POP AF ; RESTORE AF - OUT (UART0),A ; THEN WRITE THE CHAR TO UART - RET ; DONE - - -;__CRLF__________________________________________________________________________________________________________________________ -; -; SEND CR & LF TO THE SERIAL PORT -;________________________________________________________________________________________________________________________________ -; -CRLF: - PUSH HL ; PROTECT HL FROM OVERWRITE - LD HL,#TCRLF ; LOAD MESSAGE POINTER - CALL MSG ; SEBD MESSAGE TO SERIAL PORT - POP HL ; PROTECT HL FROM OVERWRITE - RET ; - - -;__LDHL__________________________________________________________________________________________________________________________ -; -; GET ONE WORD OF HEX DATA FROM BUFFER POINTED TO BY HL SERIAL PORT, RETURN IN HL -;________________________________________________________________________________________________________________________________ -; -LDHL: - PUSH DE ; STORE DE - CALL HEXIN ; GET K B. AND MAKE HEX - LD D,A ; THATS THE HI BYTE - CALL HEXIN ; DO HEX AGAIN - LD L,A ; THATS THE LOW BYTE - LD H,D ; MOVE TO HL - POP DE ; RESTORE BC - RET ; GO BACK WITH ADDRESS - - -;__HEXIN__________________________________________________________________________________________________________________________ -; -; GET ONE BYTE OF HEX DATA FROM BUFFER IN HL, RETURN IN A -;________________________________________________________________________________________________________________________________ -; -HEXIN: - PUSH BC ;SAVE BC REGS - CALL NIBL ;DO A NIBBLE - RLC A ;MOVE FIRST BYTE UPPER NIBBLE - RLC A ; - RLC A ; - RLC A ; - LD B,A ; SAVE ROTATED BYTE - CALL NIBL ; DO NEXT NIBBLE - ADD A,B ; COMBINE NIBBLES IN ACC - POP BC ; RESTORE BC - RET ; DONE -NIBL: - LD A,(HL) ; GET K B. DATA - INC HL ; INC KB POINTER - CP #0x40 ; TEST FOR ALPHA - JR NC,ALPH ; - AND #0x0F ; GET THE BITS - RET ; -ALPH: - AND #0x0F ; GET THE BITS - ADD A,#9 ; MAKE IT HEX A-F - RET ; - - -;__HEXINS_________________________________________________________________________________________________________________________ -; -; GET ONE BYTE OF HEX DATA FROM SERIAL PORT, RETURN IN A -;________________________________________________________________________________________________________________________________ -; -HEXINS: - PUSH BC ;SAVE BC REGS - CALL NIBLS ;DO A NIBBLE - RLC A ;MOVE FIRST BYTE UPPER NIBBLE - RLC A ; - RLC A ; - RLC A ; - LD B,A ; SAVE ROTATED BYTE - CALL NIBLS ; DO NEXT NIBBLE - ADD A,B ; COMBINE NIBBLES IN ACC - POP BC ; RESTORE BC - RET ; DONE -NIBLS: - CALL KIN ; GET K B. DATA - INC HL ; INC KB POINTER - CP #0x40 ; TEST FOR ALPHA - JR NC,ALPH ; - AND #0x0F ; GET THE BITS - RET ; - - -;__HXOUT_________________________________________________________________________________________________________________________ -; -; PRINT THE ACCUMULATOR CONTENTS AS HEX DATA ON THE SERIAL PORT -;________________________________________________________________________________________________________________________________ -; -HXOUT: - PUSH BC ; SAVE BC - LD B,A ; - RLC A ; DO HIGH NIBBLE FIRST - RLC A ; - RLC A ; - RLC A ; - AND #0x0F ; ONLY THIS NOW - ADD A,#0x30 ; TRY A NUMBER - CP #0x3A ; TEST IT - JR C,OUT1 ; IF CY SET PRINT 'NUMBER' - ADD A,#0x07 ; MAKE IT AN ALPHA -OUT1: - CALL COUT ; SCREEN IT - LD A,B ; NEXT NIBBLE - AND #0x0F ; JUST THIS - ADD A,#0x30 ; TRY A NUMBER - CP #0x3A ; TEST IT - JR C,OUT2 ; PRINT 'NUMBER' - ADD A,#7 ; MAKE IT ALPHA -OUT2: - CALL COUT ; SCREEN IT - POP BC ; RESTORE BC - RET ; - - -;__SPACE_________________________________________________________________________________________________________________________ -; -; PRINT A SPACE CHARACTER ON THE SERIAL PORT -;________________________________________________________________________________________________________________________________ -; -SPACE: - PUSH AF ; STORE AF - LD A,#0x20 ; LOAD A "SPACE" - CALL COUT ; SCREEN IT - POP AF ; RESTORE AF - RET ; DONE - -;__PHL_________________________________________________________________________________________________________________________ -; -; PRINT THE HL REG ON THE SERIAL PORT -;________________________________________________________________________________________________________________________________ -; -PHL: - LD A,H ; GET HI BYTE - CALL HXOUT ; DO HEX OUT ROUTINE - LD A,L ; GET LOW BYTE - CALL HXOUT ; HEX IT - CALL SPACE ; - RET ; DONE - -;__POUT__________________________________________________________________________________________________________________________ -; -; OUTPUT TO AN I/O PORT, MONITOR COMMAND "O" -;________________________________________________________________________________________________________________________________ -; -POUT: -POUT1: - INC HL ; - CALL HEXIN ; GET PORT - LD C,A ; SAVE PORT POINTER - INC HL ; - CALL HEXIN ; GET DATA -OUTIT: - OUT (C),A ; - JP SERIALCMDLOOP ; - - -;__PIN___________________________________________________________________________________________________________________________ -; -; INPUT FROM AN I/O PORT, MONITOR COMMAND "I" -;________________________________________________________________________________________________________________________________ -; -PIN: - INC HL ; - CALL HEXIN ; GET PORT - LD C,A ; SAVE PORT POINTER - CALL CRLF ; - IN A,(C) ; GET DATA - CALL HXOUT ; SHOW IT - JP SERIALCMDLOOP ; - - - - - -;__CRLFA_________________________________________________________________________________________________________________________ -; -; PRINT COMMAND PROMPT TO THE SERIAL PORT -;________________________________________________________________________________________________________________________________ -; -CRLFA: - PUSH HL ; PROTECT HL FROM OVERWRITE - LD HL,#PROMPT ; - CALL MSG ; - POP HL ; PROTECT HL FROM OVERWRITE - RET ; DONE - - -;__MSG___________________________________________________________________________________________________________________________ -; -; PRINT A STRING TO THE SERIAL PORT -;________________________________________________________________________________________________________________________________ -; -MSG: - -TX_SERLP: - LD A,(HL) ; GET CHARACTER TO A - CP #ENDT ; TEST FOR END BYTE - JP Z,TX_END ; JUMP IF END BYTE IS FOUND - CALL COUT ; - INC HL ; INC POINTER, TO NEXT CHAR - JP TX_SERLP ; TRANSMIT LOOP -TX_END: - RET ;ELSE DONE - -;__RUN___________________________________________________________________________________________________________________________ -; -; TRANSFER OUT OF MONITOR, USER OPTION "R" -;________________________________________________________________________________________________________________________________ -; -RUN: - INC HL ; SHOW READY - CALL LDHL ; GET START ADDRESS - JP (HL) ; - - -;__PROGRM________________________________________________________________________________________________________________________ -; -; PROGRAM RAM LOCATIONS, USER OPTION "P" -;________________________________________________________________________________________________________________________________ -; -PROGRM: - INC HL ; SHOW READY - PUSH HL ; STORE HL - CALL LDHL ; GET START ADDRESS - LD D,H ; - LD E,L ; DE POINTS TO ADDRESS TO PROGRAM - POP HL ; - INC HL ; - INC HL ; - INC HL ; - INC HL ; - INC HL ; -PROGRMLP: - CALL HEXIN ; GET NEXT HEX NUMBER - LD (DE),A ; STORE IT - INC DE ; NEXT ADDRESS; - CALL CRLFA ; CR,LF,> - LD A,#ASCIIP ; - CALL COUT ; - CALL SPACE ; - LD H,D ; - LD L,E ; - CALL PHL ; - LD HL,#KEYBUF ; SET POINTER TO KEYBUF AREA - CALL GETLN ; GET A LINE OF INPUT FROM THE USER - LD HL,#KEYBUF ; RESET POINTER TO START OF KEYBUF - LD A,(HL) ; LOAD FIRST CHAR INTO A - CP #0 ; END OF LINE? - JP Z,PROGRMEXIT ; YES, EXIT - JP PROGRMLP ; NO, LOOP -PROGRMEXIT: - JP SERIALCMDLOOP - - - - - - - -;__DUMP__________________________________________________________________________________________________________________________ -; -; PRINT A MEMORY DUMP, USER OPTION "D" -;________________________________________________________________________________________________________________________________ -; -DUMP: - INC HL ; SHOW READY - PUSH HL ; STORE HL - CALL LDHL ; GET START ADDRESS - LD D,H ; - LD E,L ; - POP HL ; - PUSH DE ; SAVE START - INC HL ; - INC HL ; - INC HL ; - INC HL ; - INC HL ; - CALL LDHL ; GET END ADDRESS - INC HL ; ADD ONE MORE FOR LATER COMPARE - EX DE,HL ; PUT END ADDRESS IN DE - POP HL ; GET BACK START -GDATA: - CALL CRLF ; -BLKRD: - CALL PHL ; PRINT START LOCATION - LD C,#16 ; SET FOR 16 LOCS - PUSH HL ; SAVE STARTING HL -NXTONE: - EXX ; - LD C,E ; - IN A,(C) ; - EXX ; - AND #0x7F ; - CP #ESC ; - JP Z,SERIALCMDLOOP ; - CP #19 ; - JR Z,NXTONE ; - LD A,(HL) ; GET BYTE - CALL HXOUT ; PRINT IT - CALL SPACE ; -UPDH: - INC HL ; POINT NEXT - DEC C ; DEC LOC COUNT - JR NZ,NXTONE ; IF LINE NOT DONE - ; NOW PRINT 'DECODED' DATA TO RIGHT OF DUMP -PCRLF: - CALL SPACE ; SPACE IT - LD C,#16 ; SET FOR 16 CHARS - POP HL ; GET BACK START -PCRLF0: - LD A,(HL) ; GET BYTE - AND #0x060 ; SEE IF A 'DOT' - LD A,(HL) ; O K. TO GET - JR NZ,PDOT ; -DOT: - LD A,#0x2E ; LOAD A DOT -PDOT: - CALL COUT ; PRINT IT - INC HL ; - LD A,D ; - CP H ; - JR NZ,UPDH1 ; - LD A,E ; - CP L ; - JP Z,SERIALCMDLOOP ; -; -;IF BLOCK NOT DUMPED, DO NEXT CHARACTER OR LINE -UPDH1: - DEC C ; DEC CHAR COUNT - JR NZ,PCRLF0 ; DO NEXT -CONTD: - CALL CRLF ; - JP BLKRD ; - - -;__HXLOAD__________________________________________________________________________________________________________________________ -; -; LOAD INTEL HEX FORMAT FILE FROM THE SERIAL PORT, USER OPTION "H" -; -; [INTEL HEX FORMAT IS: -; 1) COLON (FRAME 0) -; 2) RECORD LENGTH FIELD (FRAMES 1 AND 2) -; 3) LOAD ADDRESS FIELD (FRAMES 3,4,5,6) -; 4) RECORD TYPE FIELD (FRAMES 7 AND 8) -; 5) DATA FIELD (FRAMES 9 TO 9+2*(RECORD LENGTH)-1 -; 6) CHECKSUM FIELD - SUM OF ALL BYTE VALUES FROM RECORD LENGTH TO AND -; INCLUDING CHECKSUM FIELD = 0 ] -; -; EXAMPLE OF INTEL HEX FORMAT FILE -; EACH LINE CONTAINS A CARRIAGE RETURN AS THE LAST CHARACTER -; :18F900002048454C4C4F20574F524C4420FF0D0AFF0D0A3EFF0D0A54BF -; :18F918006573742050726F746F7479706520524F4D204D6F6E69746FF1 -; :18F9300072205265616479200D0AFF0D0A434F4D4D414E4420524543F2 -; :18F948004549564544203AFF0D0A434845434B53554D204552524F52CD -; :16F96000FF0A0D20202D454E442D4F462D46494C452D20200A0DA4 -; :00000001FF -;________________________________________________________________________________________________________________________________ -HXLOAD: - CALL CRLF ; SHOW READY -HXLOAD0: - CALL KIN ; GET THE FIRST CHARACTER, EXPECTING A ':' -HXLOAD1: - CP #0x3A ; IS IT COLON ':'? START OF LINE OF INTEL HEX FILE - JR NZ,HXLOADERR ; IF NOT, MUST BE ERROR, ABORT ROUTINE - LD E,#0 ; FIRST TWO CHARACTERS IS THE RECORD LENGTH FIELD - CALL HEXINS ; GET US TWO CHARACTERS INTO BC, CONVERT IT TO A BYTE - CALL HXCHKSUM ; UPDATE HEX CHECK SUM - LD D,A ; LOAD RECORD LENGTH COUNT INTO D - CALL HEXINS ; GET NEXT TWO CHARACTERS, MEMORY LOAD ADDRESS - CALL HXCHKSUM ; UPDATE HEX CHECK SUM - LD H,A ; PUT VALUE IN H REGISTER - CALL HEXINS ; GET NEXT TWO CHARACTERS, MEMORY LOAD ADDRESS - CALL HXCHKSUM ; UPDATE HEX CHECK SUM - LD L,A ; PUT VALUE IN L REGISTER - CALL HEXINS ; GET NEXT TWO CHARACTERS, RECORD FIELD TYPE - CALL HXCHKSUM ; UPDATE HEX CHECK SUM - CP #1 ; RECORD FIELD TYPE 00 IS DATA, 01 IS END OF FILE - JR NZ,HXLOAD2 ; MUST BE THE END OF THAT FILE - CALL HEXINS ; GET NEXT TWO CHARACTERS, ASSEMBLE INTO BYTE - CALL HXCHKSUM ; UPDATE HEX CHECK SUM - LD A,E ; RECALL THE CHECKSUM BYTE - AND A ; IS IT ZERO? - JP Z,HXLOADEXIT ; MUST BE O K., GO BACK FOR SOME MORE, ELSE - JR HXLOADERR ; CHECKSUMS DON'T ADD UP, ERROR OUT -HXLOAD2: - LD A,D ; RETRIEVE LINE CHARACTER COUNTER - AND A ; ARE WE DONE WITH THIS LINE? - JR Z,HXLOAD3 ; GET TWO MORE ASCII CHARACTERS, BUILD A BYTE AND CHECKSUM - CALL HEXINS ; GET NEXT TWO CHARS, CONVERT TO BYTE IN A, CHECKSUM IT - CALL HXCHKSUM ; UPDATE HEX CHECK SUM - LD (HL),A ; CHECKSUM OK, MOVE CONVERTED BYTE IN A TO MEMORY LOCATION - INC HL ; INCREMENT POINTER TO NEXT MEMORY LOCATION - DEC D ; DECREMENT LINE CHARACTER COUNTER - JR HXLOAD2 ; AND KEEP LOADING INTO MEMORY UNTIL LINE IS COMPLETE -HXLOAD3: - CALL HEXINS ; GET TWO CHARS, BUILD BYTE AND CHECKSUM - CALL HXCHKSUM ; UPDATE HEX CHECK SUM - LD A,E ; CHECK THE CHECKSUM VALUE - AND A ; IS IT ZERO? - JR Z,HXLOADAGAIN ; IF THE CHECKSUM IS STILL OK, CONTINUE ON, ELSE -HXLOADERR: - LD HL,#TXT_CKSUMERR ; GET "CHECKSUM ERROR" MESSAGE - CALL MSG ; PRINT MESSAGE FROM (HL) AND TERMINATE THE LOAD - JP HXLOADEXIT ; RETURN TO PROMPT -HXCHKSUM: - LD C,A ; BUILD THE CHECKSUM - LD A,E ; - SUB C ; THE CHECKSUM SHOULD ALWAYS .EQUAL ZERO WHEN CHECKED - LD E,A ; SAVE THE CHECKSUM BACK WHERE IT CAME FROM - LD A,C ; RETRIEVE THE BYTE AND GO BACK - RET ; BACK TO CALLER -HXLOADAGAIN: - CALL KIN ; CATCH THE TRAILING CARRIAGE RETURN - JP HXLOAD0 ; LOAD ANOTHER LINE OF DATA -HXLOADEXIT: - CALL KIN ; CATCH ANY STRAY TRAILING CHARACTERS - JP SERIALCMDLOOP ; RETURN TO PROMPT - - -;__MOVE__________________________________________________________________________________________________________________________ -; -; MOVE MEMORY, USER OPTION "M" -;________________________________________________________________________________________________________________________________ -; -MOVE: - LD C,#3 - ; START GETNM REPLACEMENT - ; GET SOURCE STARTING MEMORY LOCATION - INC HL ; SHOW EXAMINE READY - PUSH HL ; - CALL LDHL ; LOAD IN HL REGS - LD D,H ; - LD E,L ; - POP HL ; - PUSH DE ; PUSH MEMORY ADDRESS ON STACK - INC HL ; - INC HL ; - INC HL ; - INC HL ; - INC HL ; PRINT SPACE SEPARATOR - PUSH HL ; - CALL LDHL ; LOAD IN HL REGS - LD D,H ; - LD E,L ; - POP HL ; - PUSH DE ; PUSH MEMORY ADDRESS ON STACK - INC HL ; - INC HL ; - INC HL ; - INC HL ; - INC HL ; PRINT SPACE SEPARATOR - CALL LDHL ; LOAD IN HL REGS - PUSH HL ; PUSH MEMORY ADDRESS ON STACK - ; END GETNM REPLACEMENT - POP DE ; DEST - POP BC ; SOURCE END - POP HL ; SOURCE - PUSH HL ; - LD A,L ; - CPL ; - LD L,A ; - LD A,H ; - CPL ; - LD H,A ; - INC HL ; - ADD HL,BC ; - LD C,L ; - LD B,H ; - POP HL ; - CALL MOVE_LOOP ; - JP SERIALCMDLOOP ; EXIT MOVE COMMAND ROUTINE -MOVE_LOOP: - LD A,(HL) ; FETCH - LD (DE),A ; DEPOSIT - INC HL ; BUMP SOURCE - INC DE ; BUMP DEST - DEC BC ; DEC COUNT - LD A,C ; - OR B ; - JP NZ,MOVE_LOOP ; TIL COUNT=0 - RET ; - -;__FILL__________________________________________________________________________________________________________________________ -; -; FILL MEMORY, USER OPTION "M" -;________________________________________________________________________________________________________________________________ -; -FILL: - LD C,#3 ; - ; START GETNM REPLACEMENT - ; GET FILL STARTING MEMORY LOCATION - INC HL ; SHOW EXAMINE READY - PUSH HL ; - CALL LDHL ; LOAD IN HL REGS - LD D,H ; - LD E,L ; - POP HL ; - PUSH DE ; PUSH MEMORY ADDRESS ON STACK - INC HL ; - INC HL ; - INC HL ; - INC HL ; - INC HL ; PRINT SPACE SEPARATOR - ; GET FILL ENDING MEMORY LOCATION - PUSH HL ; - CALL LDHL ; LOAD IN HL REGS - LD D,H ; - LD E,L ; - POP HL ; - PUSH DE ; PUSH MEMORY ADDRESS ON STACK - INC HL ; - INC HL ; - INC HL ; - INC HL ; - INC HL ; PRINT SPACE SEPARATOR - ; GET TARGET STARTING MEMORY LOCATION - CALL HEXIN ; GET K B. AND MAKE HEX - LD C,A ; PUT FILL VALUE IN F SO IT IS SAVED FOR LATER - PUSH BC ; PUSH FILL VALUE BYTE ON STACK - ; END GETNM REPLACEMENT - POP BC ; BYTE - POP DE ; END - POP HL ; START - LD (HL),C ; -FILL_LOOP: - LD (HL),C ; - INC HL ; - LD A,E ; - SUB L ; - LD B,A ; - LD A,D ; - SUB H ; - OR B ; - JP NZ,FILL_LOOP ; - JP SERIALCMDLOOP ; - -;__GOCPM_________________________________________________________________________________________________________________________ -; -; BOOT CP/M FROM ROM DRIVE, USER OPTION "C" -;________________________________________________________________________________________________________________________________ -; -GOCPM: -;___________________________ -; REMOVE COMMENTS WHEN BURNED IN ROM -;___________________________ - -; LD A,000000000b ; RESET MPCL LATCH TO DEFAULT ROM -; OUT (MPCL),A ; -; LD HL,ROMSTART_CPM ; WHERE IN ROM CP/M IS STORED (FIRST BYTE) -; LD DE,RAMTARG_CPM ; WHERE IN RAM TO MOVE MONITOR TO (FIRST BYTE) -; LD BC,MOVSIZ_CPM ; NUMBER OF BYTES TO MOVE FROM ROM TO RAM -; LDIR ; PERFORM BLOCK COPY OF CP/M TO UPPER RAM PAGE -; LD A,010000000b ; RESET MPCL LATCH TO DEFAULT CP/M WITH 64K SETTING -; OUT (MPCL),A ; - - JP 0x0EA00 ; CP/M COLD BOOT ENTRY POINT - -; -;__INIT_UART_____________________________________________________________________________________________________________________ -; -; INITIALIZE UART -; PARAMS: SER_BAUD NEEDS TO BE SET TO BAUD RATE -; 1200: 96 = 1,843,200 / ( 16 X 1200 ) -; 2400: 48 = 1,843,200 / ( 16 X 2400 ) -; 4800: 24 = 1,843,200 / ( 16 X 4800 ) -; 9600: 12 = 1,843,200 / ( 16 X 9600 ) -; 19K2: 06 = 1,843,200 / ( 16 X 19,200 ) -; 38K4: 03 -; 57K6: 02 -; 115K2: 01 -; -;_________________________________________________________________________________________________________________________________ -; -INIT_UART: - LD A,#0x80 ; - OUT (UART3),A ; SET DLAB FLAG - LD A,(SER_BAUD) ; - OUT (UART0),A ; - LD A,#0 ; - OUT (UART1),A ; - LD A,#3 ; - OUT (UART3),A ; SET 8 BIT DATA, 1 STOPBIT - LD A,#3 ; set DTR & RTS - OUT (UART4),A ; - RET - - -; -;__FILL_MEM_______________________________________________________________________________________________________________________ -; -; FUNCTION : FILL MEMORY WITH A VALUE -; INPUT : HL = START ADDRESS BLOCK -; : BC = LENGTH OF BLOCK -; : A = VALUE TO FILL WITH -; USES : DE, BC -; OUTPUT : -; CALLS : -; TESTED : 13 FEB 2007 -;_________________________________________________________________________________________________________________________________ -; -FILL_MEM: - LD E,L ; - LD D,H ; - INC DE ; - LD (HL),A ; INITIALISE FIRST BYTE OF BLOCK WITH DATA BYTE IN A - DEC BC ; - LDIR ; FILL MEMORY - RET ; RETURN TO CALLER - -; -;__INITIALIZE_____________________________________________________________________________________________________________________ -; -; INITIALIZE SYSTEM -;_________________________________________________________________________________________________________________________________ -; -INITIALIZE: - LD A,#12 ; SPECIFY BAUD RATE 9600 BPS (9600,8,NONE,1) - LD (SER_BAUD),A ; - CALL INIT_UART ; INIT THE UART - RET ; -; - -;__MTERM_INIT________________________________________________________________________________________ -; -; SETUP 8255, MODE 0, PORT A=OUT, PORT B=IN, PORT C=OUT/OUT -; -;____________________________________________________________________________________________________ -MTERM_INIT: - LD A,#0x82 - OUT (PIOCONT),A - RET - -;__KB_GET____________________________________________________________________________________________ -; -; GET A SINGLE KEY AND DECODE -; -;____________________________________________________________________________________________________ -KB_GET: - PUSH HL ; STORE HL -KB_GET_LOOP: ; WAIT FOR KEY - CALL KB_SCAN ; SCAN KB ONCE - CP #0 ; NULL? - JR Z,KB_GET_LOOP ; LOOP WHILE NOT ZERO - LD D,A ; STORE A - LD A,#0x4F ; SCAN ALL COL LINES - OUT (PORTC),A ; SEND TO COLUMN LINES - CALL KB_SCAN_DELAY ; DELAY TO ALLOW LINES TO STABILIZE -KB_CLEAR_LOOP: ; WAIT FOR KEY TO CLEAR - IN A,(PORTB) ; GET ROWS - CP #0 ; ANYTHING PRESSED? - JR NZ,KB_CLEAR_LOOP ; YES, EXIT - LD A,D ; RESTORE A - LD D,#0x00 ; - LD HL,#KB_DECODE ; POINT TO BEGINNING OF TABLE -KB_GET_LLOOP: - CP (HL) ; MATCH? - JR Z,KB_GET_DONE ; FOUND, DONE - INC HL - INC D ; D + 1 - JP NZ,KB_GET_LLOOP ; NOT FOUND, LOOP UNTIL EOT -KB_GET_DONE: - LD A,D ; RESULT INTO A - POP HL ; RESTORE HL - RET - - - -;__KB_SCAN____________________________________________________________________________________________ -; -; SCAN KEYBOARD MATRIX FOR AN INPUT -; -;____________________________________________________________________________________________________ -KB_SCAN: - - LD C,#0 - LD A,#0x41 ; SCAN COL ONE - OUT (PORTC),A ; SEND TO COLUMN LINES - CALL KB_SCAN_DELAY ; DELAY TO ALLOW LINES TO STABILIZE - IN A,(PORTB) ; GET ROWS - CP #0x00 ; ANYTHING PRESSED? - JR NZ,KB_SCAN_FOUND ; YES, EXIT - - LD C,#0x0040 - LD A,#0x42 ; SCAN COL TWO - OUT (PORTC),A ; SEND TO COLUMN LINES - CALL KB_SCAN_DELAY ; DELAY TO ALLOW LINES TO STABILIZE - IN A,(PORTB) ; GET ROWS - CP #0 ; ANYTHING PRESSED? - JR NZ,KB_SCAN_FOUND ; YES, EXIT - - LD C,#0x0080 - LD A,#0x44 ; SCAN COL THREE - OUT (PORTC),A ; SEND TO COLUMN LINES - CALL KB_SCAN_DELAY ; DELAY TO ALLOW LINES TO STABILIZE - IN A,(PORTB) ; GET ROWS - CP #0x00 ; ANYTHING PRESSED? - JR NZ,KB_SCAN_FOUND ; YES, EXIT - - LD C,#0x00C0 ; - LD A,#0x48 ; SCAN COL FOUR - OUT (PORTC),A ; SEND TO COLUMN LINES - CALL KB_SCAN_DELAY ; DELAY TO ALLOW LINES TO STABILIZE - IN A,(PORTB) ; GET ROWS - CP #0x00 ; ANYTHING PRESSED? - JR NZ,KB_SCAN_FOUND ; YES, EXIT - - LD A, #0x40 ; TURN OFF ALL COLUMNS - OUT (PORTC),A ; SEND TO COLUMN LINES - LD A, #0x00 ; RETURN NULL - RET ; EXIT - -KB_SCAN_FOUND: - AND #0x3F ; CLEAR TOP TWO BITS - OR C ; ADD IN ROW BITS - LD C,A ; STORE VALUE - LD A,#0x00 ; TURN OFF ALL COLUMNS - OUT (PORTC),A ; SEND TO COLUMN LINES - LD A,C ; RESTORE VALUE - RET - -PAUSE: -KB_SCAN_DELAY: - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP - RET - - - -;__HEXDISPLAY________________________________________________________________________________________ -; -; DISPLAY CONTENTS OF DISPLAYBUF IN DECODED HEX BITS 0-3 ARE DISPLAYED DIG, BIT 7 IS DP -; -;____________________________________________________________________________________________________ -HEXDISPLAY: - PUSH HL ; STORE HL - PUSH AF ; STORE AF - PUSH BC ; STORE BC - LD BC,#0007 - ADD HL,BC - LD B,#0x08 ; SET DIGIT COUNT - LD A,#0x40 ; SET CONTROL PORT 7218 TO OFF - OUT (PORTC),A ; OUTPUT - CALL PAUSE ; WAIT - LD A,#0x0F0 ; SET CONTROL TO 1111 (DATA COMING, HEX DECODE,NO DECODE, NORMAL) - OUT (PORTA),A ; OUTPUT TO PORT - LD A,#0x80 ; STROBE WRITE PULSE WITH CONTROL=1 - OUT (PORTC),A ; OUTPUT TO PORT - CALL PAUSE ; WAIT - LD A,#0x40 ; SET CONTROL PORT 7218 TO OFF - OUT (PORTC),A ; OUTPUT -HEXDISPLAY_LP: - LD A,(HL) ; GET DISPLAY DIGIT - CALL DECODEDISPLAY ; DECODE DISPLAY - OUT (PORTA),A ; OUT TO PORTA - LD A,#0x00 ; SET WRITE STROBE - OUT (PORTC),A ; OUT TO PORTC - CALL PAUSE ; DELAY - LD A,#0x40 ; SET CONTROL PORT OFF - OUT (PORTC),A ; OUT TO PORTC - CALL PAUSE ; WAIT - DEC HL ; INC POINTER - DJNZ HEXDISPLAY_LP ; LOOP FOR NEXT DIGIT - POP BC ; RESTORE BC - POP AF ; RESTORE AF - POP HL ; RESTORE HL - RET - -;__DECODEDISPLAY_____________________________________________________________________________________ -; -; DISPLAY CONTENTS OF DISPLAYBUF IN DECODED HEX BITS 0-3 ARE DISPLAYED DIG, BIT 7 IS DP -; -;____________________________________________________________________________________________________ -DECODEDISPLAY: - PUSH BC ; STORE BC - PUSH HL ; STORE HL - LD HL,#SEGDECODE ; POINT HL TO DECODE TABLE - LD B,#0x00 ; RESET HIGH BYTE - LD C,A ; CHAR INTO LOW BYTE - ADD HL,BC ; SET TABLE POINTER - LD A,(HL) ; GET VALUE - POP HL ; RESTORE HL - POP BC ; RESTORE BC - RET - - -;__SEGDISPLAY________________________________________________________________________________________ -; -; DISPLAY CONTENTS OF DISPLAYBUF IN DECODED HEX BITS 0-3 ARE DISPLAYED DIG, BIT 7 IS DP -; -;____________________________________________________________________________________________________ -SEGDISPLAY: - PUSH AF ; STORE AF - PUSH BC ; STORE BC - LD BC,#0x0007 - ADD HL,BC - LD B,#0x08 ; SET DIGIT COUNT - LD A,#0x40 ; SET CONTROL PORT 7218 TO OFF - OUT (PORTC),A ; OUTPUT - CALL PAUSE ; WAIT - LD A,#0x0F0 ; SET CONTROL TO 1111 (DATA COMING, HEX DECODE,NO DECODE, NORMAL) - OUT (PORTA),A ; OUTPUT TO PORT - LD A,#0x80 ; STROBE WRITE PULSE WITH CONTROL=1 - OUT (PORTC),A ; OUTPUT TO PORT - CALL PAUSE ; WAIT - LD A,#0x40 ; SET CONTROL PORT 7218 TO OFF - OUT (PORTC),A ; OUTPUT -SEGDISPLAY_LP: - LD A,(HL) ; GET DISPLAY DIGIT - OUT (PORTA),A ; OUT TO PORTA - LD A,#0x00 ; SET WRITE STROBE - OUT (PORTC),A ; OUT TO PORTC - CALL PAUSE ; DELAY - LD A,#0x40 ; SET CONTROL PORT OFF - OUT (PORTC),A ; OUT TO PORTC - CALL PAUSE ; WAIT - DEC HL ; INC POINTER - DJNZ SEGDISPLAY_LP ; LOOP FOR NEXT DIGIT - POP BC ; RESTORE BC - POP AF ; RESTORE AF - RET - -; -;__WORK_AREA___________________________________________________________________________________________________________________ -; -; RESERVED RAM FOR MONITOR WORKING AREA -;_____________________________________________________________________________________________________________________________ -; -SER_BAUD: .DS 1 ; SPECIFY DESIRED UART COM RATE IN BPS -KEYBUF: .ascii " " - .ascii " " -DISPLAYBUF: .DB 00,00,00,00,00,00,00,00 -IDEDEVICE: .DB 1 ; IDE DRIVE SELECT FLAG (00H=PRIAMRY, 10H = SECONDARY) -IDE_SECTOR_BUFFER: - .DS 0x00200 - - - - -; -;__TEXT_STRINGS_________________________________________________________________________________________________________________ -; -; SYSTEM TEXT STRINGS -;_____________________________________________________________________________________________________________________________ -; -TCRLF: - .DB CR,LF,ENDT - -PROMPT: - .DB CR,LF - .ascii ">" - .DB ENDT - -TXT_READY: - .DB CR,LF - .ascii " NN NN 8888 VV VV EEEEEEEEEE MM MM" - .DB CR,LF - .ascii " NNNN NN 88 88 VV VV EE MMMM MMMM" - .DB CR,LF - .ascii " NN NN NN 88 88 VV VV EE MM MM MM MM" - .DB CR,LF - .ascii " NN NNNN 88 88 VV VV EE MM MM MM" - .DB CR,LF - .ascii " NN NN 8888 VV VV EEEEEEE MM MM" - .DB CR,LF - .ascii " NN NN 88 88 VV VV EE MM MM" - .DB CR,LF - .ascii " NN NN 88 88 VV VV EE MM MM" - .DB CR,LF - .ascii " NN NN 88 88 VVV EE MM MM" - .DB CR,LF - .ascii " NN NN 8888 V EEEEEEEEEE MM MM S B C" - .DB CR,LF - .DB CR,LF - .ascii " ****************************************************************************" - .DB CR,LF - .ascii "MONITOR READY " - .DB CR,LF,ENDT - -TXT_COMMAND: - .DB CR,LF - .ascii "UNKNOWN COMMAND." - .DB ENDT - -TXT_CKSUMERR: - .DB CR,LF - .ascii "CHECKSUM ERROR." - .DB ENDT -CPUUP: - .DB 0x084,0x0EE,0x0BB,0x080,0x0BB,0x0EE,0x0CB,0x084 -ADDR: - .DB 0x00,0x00,0x00,0x00,0x08C,0x0BD,0x0BD,0x0FE - - -PORT: - .DB 0x00,0x00,0x80,0x80,0x094,0x08C,0x09D,0x0EE -SEC: - .DB 0x80,0x80,0x80,0x80,0x80,0x0CB,0x0CF,0x0D7 - - -;_KB DECODE TABLE__________________________________________________________________________________________________________ -; -; -KB_DECODE: -; 0 1 2 3 4 5 6 7 8 9 A B C D E F - .DB 0x41,0x02,0x42,0x82,0x04,0x44,0x84,0x08,0x48,0x88,0x10,0x50,0x90,0x20,0x60,0x0A0 -; FW BK CL EN DP EX GO BO - .DB 0x01,0x81,0x0C1,0x0C2,0x0C4,0x0C8,0x0D0,0x0E0 -; -; F-KEYS, -; FW = FORWARD -; BK = BACKWARD -; CL = CLEAR -; EN = ENTER -; DP = DEPOSIT (INTO MEM) -; EX = EXAMINE (MEM) -; GO = GO -; BO = BOOT -;_________________________________________________________________________________________________________________________ -;_HEX 7_SEG_DECODE_TABLE__________________________________________________________________________________________________ -; -; 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F, ,- -; AND WITH 7FH TO TURN ON DP -;_________________________________________________________________________________________________________________________ -SEGDECODE: - .DB 0x0FB,0x0B0,0x0ED,0x0F5,0x0B6,0x0D7,0x0DF,0x0F0,0x0FF,0x0F7,0x0FE,0x09F,0x0CB,0x0BD,0x0CF,0x0CE,0x080,0x084,0x00,0x0EE,0x09D - -;********************* END OF PROGRAM *********************************** - -;dwg; .ORG 08FFFh -;dwg; .DB 000h -;dwg; .END - -_dbgmon_end:: - .area _CODE - .area _CABS diff --git a/doug/src/dbgmon.sym b/doug/src/dbgmon.sym deleted file mode 100755 index 0caa3602..00000000 --- a/doug/src/dbgmon.sym +++ /dev/null @@ -1,83 +0,0 @@ - ASxxxx Assembler V02.00 + NoICE + SDCC mods + Flat24 (Zilog Z80 / Hitachi HD64180), page 1. -dbgmon.s derived from dbgmon.asm -Symbol Table - - .__.ABS.= 0000 G | 6 ADDR 0CCF R | 6 ALPH 0405 R - ASCIIA = 0041 | ASCIIB = 0042 | ASCIIC = 0043 - ASCIID = 0044 | ASCIIE = 0045 | ASCIIF = 0046 - ASCIIG = 0047 | ASCIIH = 0048 | ASCIII = 0049 - ASCIIJ = 004A | ASCIIK = 004B | ASCIIL = 004C - ASCIIM = 004D | ASCIIN = 004E | ASCIIO = 004F - ASCIIP = 0050 | ASCIIQ = 0051 | ASCIIR = 0052 - ASCIIS = 0053 | ASCIIT = 0054 | ASCIIU = 0055 - ASCIIV = 0056 | ASCIIW = 0057 | ASCIIX = 0058 - ASCIIY = 0059 | ASCIIZ = 005A | 6 BLKRD 04EB R - BS = 0008 | 6 CONTD 052A R | 6 COUT 03C8 R - 6 CPUUP 0CC7 R | CR = 000D | 6 CRLF 03D4 R - 6 CRLFA 0481 R | 6 DECODEDI 06F8 R | 6 DEPOSITE 011B R - 6 DEPOSITF 0117 R | 6 DEPOSITG 0105 R | 6 DEPOSITL 00D4 R - 6 DISPLAYB 078B R | 6 DOBOOT 0033 R | 6 DODEPOSI 00D0 R - 6 DOEXAMIN 0124 R | 6 DOGO 00CC R | 6 DOPORTRE 003C R - 6 DOPORTWR 0094 R | 6 DOT 0518 R | 6 DSPSECTO 022B R - 6 DUMP 04D4 R | ENDT = 00FF | ESC = 001B - 6 EXAMINEE 0180 R | 6 EXAMINEF 017C R | 6 EXAMINEG 016A R - 6 EXAMINEL 0128 R | 6 EXIT 0032 R | 6 FILL 05DD R - 6 FILL_LOO 0603 R | 6 FILL_MEM 062A R | 6 FRONTPAN 000F R - 6 GDATA 04E8 R | 6 GETADDR 0189 R | 6 GETADDR1 018C R - 6 GETADDRC 01F6 R | 6 GETADDRD 0204 R | 6 GETADDRD 01A4 R - 6 GETADDRL 0192 R | 6 GETADDRN 01DD R | 6 GETLN 0381 R - 6 GETLNDON 03B0 R | 6 GETLNLOP 0384 R | 6 GETLNSTO 03A8 R - 6 GETPORT 026C R | 6 GETPORT1 026F R | 6 GETPORTC 02B2 R - 6 GETPORTD 02BA R | 6 GETPORTD 0287 R | 6 GETPORTL 0275 R - 6 GETPORTN 02A5 R | 6 GETVALUE 02CF R | 6 GETVALUE 02D2 R - 6 GETVALUE 0312 R | 6 GETVALUE 02E7 R | 6 GETVALUE 02D5 R - 6 GETVALUE 0305 R | 6 GOCPM 0611 R | 6 HEXDISPL 06BE R - 6 HEXDISPL 06DD R | 6 HEXIN 03E9 R | 6 HEXINS 040A R - 6 HXCHKSUM 058A R | 6 HXLOAD 0530 R | 6 HXLOAD0 0533 R - 6 HXLOAD1 0536 R | 6 HXLOAD2 0568 R | 6 HXLOAD3 0577 R - 6 HXLOADAG 0590 R | 6 HXLOADER 0581 R | 6 HXLOADEX 0596 R - 6 HXOUT 0428 R | IDEADDR = 002F | IDECTRL = 002E - IDECYLHI= 0025 | IDECYLLO= 0024 | 6 IDEDEVIC 0793 R - IDEERR = 0021 | IDEHEAD = 0026 | IDEHI = 0028 - IDELO = 0020 | IDESECTC= 0022 | IDESECTN= 0023 - IDESTTS = 0027 | 6 IDE_SECT 0794 R | 6 INITIALI 0632 R - 6 INIT_UAR 0614 R | 6 KB_CLEAR 0650 R | 6 KB_DECOD 0CE7 R - 6 KB_GET 0640 R | 6 KB_GET_D 0664 R | 6 KB_GET_L 065C R - 6 KB_GET_L 0641 R | 6 KB_SCAN 0667 R | 6 KB_SCAN_ 06B4 R - 6 KB_SCAN_ 06AA R | 6 KEYBUF 073B R | 6 KIN 03B4 R - 6 KLOP 0374 R | 6 LDHL 03DD R | LF = 000A - MONSTART= 8000 | 6 MONSTART 031D R | 6 MOVE 059C R - 6 MOVE_LOO 05D2 R | MPCL = 0078 | MPCL_RAM= 0078 - MPCL_ROM= 007C | 6 MSG 048A R | 6 MTERM_IN 063B R - 6 NIBL 03FC R | 6 NIBLS 041D R | 6 NXTONE 04F1 R - 6 OUT1 043C R | 6 OUT2 044A R | 6 OUTIT 046C R - 6 PAUSE 06B4 R | 6 PCRLF 050C R | 6 PCRLF0 0512 R - 6 PDOT 051A R | 6 PHL 0457 R | 6 PIN 0471 R - PIOCONT = 0063 | 6 PORT 0CD7 R | PORTA = 0060 - PORTB = 0061 | PORTC = 0062 | 6 PORTREAD 008B R - 6 PORTREAD 007D R | 6 PORTREAD 003F R | 6 PORTWRIT 0097 R - 6 POUT 0463 R | 6 POUT1 0463 R | 6 PROGRM 049D R - 6 PROGRMEX 04D1 R | 6 PROGRMLP 04AA R | 6 PROMPT 0997 R - RAMBOTTO= 8000 | RAMTOP = FFFF | 6 RUN 0498 R - 6 SEC 0CDF R | 6 SEGDECOD 0CFF R | 6 SEGDISPL 0705 R - 6 SEGDISPL 0723 R | 6 SERIALCM 032C R | 6 SER_BAUD 073A R - 6 SPACE 044F R | STACKSTA= CFFF | 6 TCRLF 0994 R - 6 TXT_CKSU 0CB5 R | 6 TXT_COMM 0CA2 R | 6 TXT_READ 099B R - 6 TX_BUSYL 03C9 R | 6 TX_END 0497 R | 6 TX_SERLP 048A R - UART0 = 0068 | UART1 = 0069 | UART2 = 006A - UART3 = 006B | UART4 = 006C | UART5 = 006D - UART6 = 006E | UART7 = 006F | 6 UPDH 0508 R - 6 UPDH1 0527 R | 6 _dbgmon 0000 GR | 6 _dbgmon_ 0D14 GR - 6 _dbgmon_ 0000 GR - ASxxxx Assembler V02.00 + NoICE + SDCC mods + Flat24 (Zilog Z80 / Hitachi HD64180), page 2. -dbgmon.s derived from dbgmon.asm -Area Table - - 0 _CODE size 0 flags 0 - 1 _DATA size 0 flags 0 - 2 _OVERLAY size 0 flags 0 - 3 _HOME size 0 flags 0 - 4 _GSINIT size 0 flags 0 - 5 _GSFINAL size 0 flags 0 - 6 _DBGMON size D14 flags 0 - 7 _CABS size 0 flags 0 diff --git a/doug/src/dribdos.lst b/doug/src/dribdos.lst deleted file mode 100755 index c4d9e863..00000000 --- a/doug/src/dribdos.lst +++ /dev/null @@ -1,2838 +0,0 @@ - 1 ;-------------------------------------------------------- - 2 ; File Created by SDCC : free open source ANSI-C Compiler - 3 ; Version 3.0.2 #6489 (May 10 2011) (Mac OS X x86_64) - 4 ; This file was generated Sun May 29 01:02:12 2011 - 5 ;-------------------------------------------------------- - 6 .module dribdos - 7 .optsdcc -mz80 - 8 - 9 ;-------------------------------------------------------- - 10 ; Public variables in this module - 11 ;-------------------------------------------------------- - 12 .globl _bdos - 13 ;-------------------------------------------------------- - 14 ; special function registers - 15 ;-------------------------------------------------------- - 16 ;-------------------------------------------------------- - 17 ; ram data - 18 ;-------------------------------------------------------- - 19 .area _DATA - 20 ;-------------------------------------------------------- - 21 ; overlayable items in ram - 22 ;-------------------------------------------------------- - 23 .area _OVERLAY - 24 ;-------------------------------------------------------- - 25 ; external initialized ram data - 26 ;-------------------------------------------------------- - 27 ;-------------------------------------------------------- - 28 ; global & static initialisations - 29 ;-------------------------------------------------------- - 30 .area _HOME - 31 .area _GSINIT - 32 .area _GSFINAL - 33 .area _GSINIT - 34 ;-------------------------------------------------------- - 35 ; Home - 36 ;-------------------------------------------------------- - 37 .area _HOME - 38 .area _HOME - 39 ;-------------------------------------------------------- - 40 ; code - 41 ;-------------------------------------------------------- - 42 .area _BDOS - 43 ;dribdos.c:4: void bdos(int argc,char **argv) - 44 ; --------------------------------- - 45 ; Function bdos - 46 ; --------------------------------- - 0000 47 _bdos_start:: - 0000 48 _bdos: - 49 ;; push ix - 50 ;; ld ix,#0 - 51 ;; add ix,sp - 52 ;; ;dribdos.c:7: } - 53 ;; pop ix - 54 ;; ret - 55 - 56 ;; dwg ; begin DRI source code here - 57 - 58 .title 'Bdos Interface, Bdos, Version 2.2 Feb, 1980' - 59 - 60 ;;dwg;;: .Z80 - 61 ;; aseg -o 0000 62 org 100h -o 0000 63 maclib MEMCFG.LIB ; define configuration parameters -o 0000 64 .phase bdosph -o 0000 65 bios equ biosph - 66 - 67 ;***************************************************************** - 68 ;***************************************************************** - 69 ;** ** - 70 ;** B a s i c D i s k O p e r a t i n g S y s t e m ** - 71 ;** I n t e r f a c e M o d u l e ** - 72 ;** ** - 73 ;***************************************************************** - 74 ;***************************************************************** - 75 - 76 ; Copyright (c) 1978, 1979, 1980 - 77 ; Digital Research - 78 ; Box 579, Pacific Grove - 79 ; California - 80 - 81 - 82 ; 20 january 1980 - 83 -o 0000 84 ssize equ 24 ;24 level stack - 85 - 86 ; low memory locations -o 0000 87 reboot equ 0000h ;reboot system -o 0000 88 ioloc equ 0003h ;i/o byte location -o 0000 89 bdosa equ 0006h ;address field of jp BDOS - 90 - 91 ; bios access constants -o 0000 92 bootf defl bios+3*0 ;cold boot function -o 0000 93 wbootf defl bios+3*1 ;warm boot function -o 0000 94 constf defl bios+3*2 ;console status function -o 0000 95 coninf defl bios+3*3 ;console input function -o 0000 96 conoutf defl bios+3*4 ;console output function -o 0000 97 listf defl bios+3*5 ;list output function -o 0000 98 punchf defl bios+3*6 ;punch output function -o 0000 99 readerf defl bios+3*7 ;reader input function -o 0000 100 homef defl bios+3*8 ;disk home function -o 0000 101 seldskf defl bios+3*9 ;select disk function -o 0000 102 settrkf defl bios+3*10 ;set track function -o 0000 103 setsecf defl bios+3*11 ;set sector function -o 0000 104 setdmaf defl bios+3*12 ;set dma function -o 0000 105 readf defl bios+3*13 ;read disk function -o 0000 106 writef defl bios+3*14 ;write disk function -o 0000 107 liststf defl bios+3*15 ;list status function -o 0000 108 sectran defl bios+3*16 ;sector translate - 109 - 110 ; equates for non graphic characters -o 0000 111 ctlc equ 03h ;control c -o 0000 112 ctle equ 05h ;physical eol -o 0000 113 ctlh equ 08h ;backspace -o 0000 114 ctlp equ 10h ;prnt toggle -o 0000 115 ctlr equ 12h ;repeat line -o 0000 116 ctls equ 13h ;stop/start screen -o 0000 117 ctlu equ 15h ;line delete -o 0000 118 ctlx equ 18h ;=ctl-u -o 0000 119 ctlz equ 1ah ;end of file -o 0000 120 rubout equ 7fh ;char delete -o 0000 121 tab equ 09h ;tab char -o 0000 122 cr equ 0dh ;carriage return -o 0000 123 lf equ 0ah ;line feed -o 0000 124 ctl equ 5eh ;up arrow - 125 - 0000 00 00 00 00 00 00 126 .db 0,0,0,0,0,0 - 127 - 128 ; enter here from the user's program with function number in c, - 129 ; and information address in d,e - 0006 C3r11s00 130 jp bdose ;past parameter block - 131 - 132 ; ************************************************ - 133 ; *** relative locations 0009 - 000e *** - 134 ; ************************************************ - 0009r37s00 135 pererr: .dw persub ;permanent error subroutine - 000Br3Es00 136 selerr: .dw selsub ;select error subroutine - 000Dr41s00 137 roderr: .dw rodsub ;ro disk error subroutine - 000Fr44s00 138 roferr: .dw rofsub ;ro file error subroutine - 139 - 140 - 0011 EB 141 bdose: ex de,hl ;arrive here from user programs - 0012 22rFCs01 142 ld (info),hl - 0015 EB 143 ex de,hl ;info=DE, DE=info - 0016 7B 144 ld a,e - 0017 32rC6s0A 145 ld (linfo),a ;linfo = low(info) - don't equ -a 001A 146 ld hl,0 - 001A 22rFCs01 147 ld (aret),hl ;return value defaults to 0000 - 148 ;save user's stack pointer, set to local stack - 001D 39 149 add hl,sp - 001E 22rFCs01 150 ld (entsp),hl ;entsp = stackptr -a 0021 151 ld sp,lstack ;local stack setup - 0021 AF 152 xor a - 0022 32rC6s0A 153 ld (fcbdsk),a - 0025 32rC6s0A 154 ld (resel),a ;fcbdsk,resel=false -a 0028 155 ld hl,goback ;return here after all functions - 0028 E5 156 push hl ;jmp goback equivalent to ret - 0029 79 157 ld a,c -ua 002A 158 cp nfuncs - 002A D0 159 ret nc ;skip if invalid # - 002B 4B 160 ld c,e ;possible output character to C -a 002C 161 ld hl,functab - 002C 5F 162 ld e,a -a 002D 163 ld d,0 ;DE=func, HL=.ciotab - 002D 19 164 add hl,de - 002E 19 165 add hl,de - 002F 5E 166 ld e,(hl) - 0030 23 167 inc hl - 0031 56 168 ld d,(hl) ;DE=functab(func) - 0032 2ArFCs01 169 ld hl,(info) ;info in DE for later xchg - 0035 EB 170 ex de,hl - 0036 E9 171 jp (hl) ;dispatched - 172 - 173 ; dispatch table for functions - 0037 174 functab: -o 0037 175 dw wbootf, func1, func2, func3 -o 0037 176 dw punchf, listf, func6, func7 -o 0037 177 dw func8, func9, func10,func11 -o 0037 178 diskf equ ($-functab)/2 ;disk funcs -o 0037 179 dw func12,func13,func14,func15 -o 0037 180 dw func16,func17,func18,func19 -o 0037 181 dw func20,func21,func22,func23 -o 0037 182 dw func24,func25,func26,func27 -o 0037 183 dw func28,func29,func30,func31 -o 0037 184 dw func32,func33,func34,func35 -o 0037 185 dw func36,func37,func38,func39 -o 0037 186 dw func40 -o 0037 187 nfuncs equ ($-functab)/2 - 188 - 189 - 190 ; error subroutines -a 0037 191 persub: ld hl,permsg ;report permanent error - 0037 CDr4As00 192 call errflg ;to report the error -ua 003A 193 cp ctlc -u 003A CA 00 00 194 jp z,reboot ;reboot if response is ctlc - 003D C9 195 ret ;and ignore the error - 196 -a 003E 197 selsub: ld hl,selmsg ;report select error - 003E C3r44s00 198 jp wait$err ;wait console before boot - 199 -a 0041 200 rodsub: ld hl,rodmsg ;report write to read/only disk - 0041 C3r44s00 201 jp wait$err ;wait console - 202 - 0044 203 rofsub: ;report read/only file -a 0044 204 ld hl,rofmsg ;drop through to wait for console - 205 - 0044 206 wait$err: ;wait for response before boot - 0044 CDr4As00 207 call errflg -u 0047 C3 00 00 208 jp reboot - 209 - 210 ; error messages -o 004A 211 dskmsg: db 'Bdos Err On ' -o 004A 212 dskerr: db ' : $' ;filled in by errflg -o 004A 213 permsg: db 'Bad Sector$' -o 004A 214 selmsg: db 'Select$' -o 004A 215 rofmsg: db 'File ' -o 004A 216 rodmsg: db 'R/O$' - 217 - 218 - 004A E5 219 errflg: push hl ;report error to console, message address in HL - 004B CDrF0s00 220 call crlf ;stack mssg address, new line - 004E 3ArFCs01 221 ld a,(curdsk) -aq 0051 222 add a,'A' - 0051 32r4As00 223 ld (dskerr),a ;current disk name -a 0054 224 ld bc,dskmsg - 0054 CDrF6s00 225 call print ;the error message - 0057 C1 226 pop bc - 0058 CDrF6s00 227 call print ;error mssage tail - 228 ; jp conin ;to get the input character - 229 ;(drop through to conin) - 230 ; ret - 231 - 232 - 233 ; console handlers -a 005B 234 conin: ld hl,kbchar ;read console character to A - 005B 7E 235 ld a,(hl) -a 005C 236 ld (hl),0 - 005C B7 237 or a - 005D C0 238 ret nz - 239 ;no previous keyboard character ready -u 005E C3 00 00 240 jp coninf ;get character externally - 241 ; ret - 0061 CDr5Bs00 242 conech: call conin ;read character with echo - 0064 CDr6Fs00 243 call echoc - 0067 D8 244 ret c ;echo character? - 245 ;character must be echoed before return - 0068 F5 246 push af - 0069 4F 247 ld c,a - 006A CDrC8s00 248 call tabout - 006D F1 249 pop af - 006E C9 250 ret ;with character in A - 251 - 006F 252 echoc: ;echo character if graphic -ua 006F 253 cp cr ;cr, lf, tab, or backspace - 006F C8 254 ret z ;carriage return? -ua 0070 255 cp lf - 0070 C8 256 ret z ;line feed? -ua 0071 257 cp tab - 0071 C8 258 ret z ;tab? -ua 0072 259 cp ctlh - 0072 C8 260 ret z ;backspace? -q 0073 261 cp ' ' - 0073 C9 262 ret ;carry set if not graphic - 263 - 0074 264 conbrk: ;check for character ready - 0074 3ArFCs01 265 ld a,(kbchar) - 0077 B7 266 or a - 0078 C2r90s00 267 jp nz,conb1 ;skip if active kbchar - 268 ;no active kbchar, check external break -u 007B CD 00 00 269 call constf -a 007E 270 and 1 - 007E C8 271 ret z ;return if no char ready - 272 ;character ready, read it -u 007F CD 00 00 273 call coninf ;to A -ua 0082 274 cp ctls - 0082 C2r8Ds00 275 jp nz,conb0 ;check stop screen function - 276 ;found ctls, read next character -u 0085 CD 00 00 277 call coninf ;to A -ua 0088 278 cp ctlc -u 0088 CA 00 00 279 jp z,reboot ;ctlc implies re-boot - 280 ;not a reboot, act as if nothing has happened - 008B AF 281 xor a - 008C C9 282 ret ;with zero in accumulator - 008D 283 conb0: - 284 ;character in accum, save it - 008D 32rFCs01 285 ld (kbchar),a - 0090 286 conb1: - 287 ;return with true set in accumulator -a 0090 288 ld a,1 - 0090 C9 289 ret - 290 - 0091 291 conout: ;compute character position/write console char from C - 292 ;compcol = true if computing column position - 0091 3ArFCs01 293 ld a,(compcol) - 0094 B7 294 or a - 0095 C2rABs00 295 jp nz,compout - 296 ;write the character, then compute the column - 297 ;write console character from C - 0098 C5 298 push bc - 0099 CDr74s00 299 call conbrk ;check for screen stop function - 009C C1 300 pop bc - 009D C5 301 push bc ;recall/save character -u 009E CD 00 00 302 call conoutf ;externally, to console - 00A1 C1 303 pop bc - 00A2 C5 304 push bc ;recall/save character - 305 ;may be copying to the list device - 00A3 3ArFCs01 306 ld a,(listcp) - 00A6 B7 307 or a -u 00A7 C4 00 00 308 call nz,listf ;to printer, if so - 00AA C1 309 pop bc ;recall the character - 00AB 310 compout: - 00AB 79 311 ld a,c ;recall the character - 312 ;and compute column position -a 00AC 313 ld hl,column ;A = char, HL = .column -ua 00AC 314 cp rubout - 00AC C8 315 ret z ;no column change if nulls - 00AD 34 316 inc (hl) ;column = column + 1 -q 00AE 317 cp ' ' - 00AE D0 318 ret nc ;return if graphic - 319 ;not graphic, reset column position - 00AF 35 320 dec (hl) ;column = column - 1 - 00B0 7E 321 ld a,(hl) - 00B1 B7 322 or a - 00B2 C8 323 ret z ;return if at zero - 324 ;not at zero, may be backspace or end line - 00B3 79 325 ld a,c ;character back to A -ua 00B4 326 cp ctlh - 00B4 C2rB9s00 327 jp nz,notbacksp - 328 ;backspace character - 00B7 35 329 dec (hl) ;column = column - 1 - 00B8 C9 330 ret - 331 - 00B9 332 notbacksp: ;not a backspace character, eol? -ua 00B9 333 cp lf - 00B9 C0 334 ret nz ;return if not - 335 ;end of line, column = 0 -a 00BA 336 ld (hl),0 ;column = 0 - 00BA C9 337 ret - 338 - 00BB 339 ctlout: ;send C character with possible preceding up-arrow - 00BB 79 340 ld a,c - 00BC CDr6Fs00 341 call echoc ;cy if not graphic (or special case) - 00BF D2rC8s00 342 jp nc,tabout ;skip if graphic, tab, cr, lf, or ctlh - 343 ;send preceding up arrow - 00C2 F5 344 push af -ua 00C3 345 ld c,ctl - 00C3 CDr91s00 346 call conout ;up arrow - 00C6 F1 347 pop af -q 00C7 348 or 40h ;becomes graphic letter - 00C7 4F 349 ld c,a ;ready to print - 350 ;(drop through to tabout) - 351 - 00C8 352 tabout: ;expand tabs to console - 00C8 79 353 ld a,c -ua 00C9 354 cp tab - 00C9 C2r91s00 355 jp nz,conout ;direct to conout if not - 356 ;tab encountered, move to next tab position -aq 00CC 357 tab0: ld c,' ' - 00CC CDr91s00 358 call conout ;another blank - 00CF 3ArFCs01 359 ld a,(column) -q 00D2 360 and 111b ;column mod 8 = 0 ? - 00D2 C2rCCs00 361 jp nz,tab0 ;back for another if not - 00D5 C9 362 ret - 363 - 00D6 364 backup: ;back-up one screen position - 00D6 CDrDCs00 365 call pctlh -aq 00D9 366 ld c,' ' -u 00D9 CD 00 00 367 call conoutf - 368 ; (drop through to pctlh) - 00DC 369 pctlh: ;send ctlh to console without affecting column count -ua 00DC 370 ld c,ctlh -u 00DC C3 00 00 371 jp conoutf - 372 ; ret - 00DF 373 crlfp: ;print #, cr, lf for ctlx, ctlu, ctlr functions - 374 ;then move to strtcol (starting column) -aq 00DF 375 ld c,'#' - 00DF CDr91s00 376 call conout - 00E2 CDrF0s00 377 call crlf ;column = 0, move to position strtcol - 00E5 3ArFCs01 378 crlfp0: ld a,(column) -a 00E8 379 ld hl,strtcol - 00E8 BE 380 cp (hl) - 00E9 D0 381 ret nc ;stop when column reaches strtcol -aq 00EA 382 ld c,' ' - 00EA CDr91s00 383 call conout ;print blank - 00ED C3rE5s00 384 jp crlfp0 - 385 -ua 00F0 386 crlf: ld c,cr ;carriage return line feed sequence - 00F0 CDr91s00 387 call conout -ua 00F3 388 ld c,lf - 00F3 C3r91s00 389 jp conout - 390 ; ret - 00F6 0A 391 print: ld a,(bc) ;print message until M(BC) = '$' -q 00F7 392 cp '$' - 00F7 C8 393 ret z ;stop on $ - 394 ;more to print - 00F8 03 395 inc bc - 00F9 C5 396 push bc - 00FA 4F 397 ld c,a ;char to C - 00FB CDrC8s00 398 call tabout ;another character printed - 00FE C1 399 pop bc - 00FF C3rF6s00 400 jp print - 401 - 0102 402 read: ;read to info address (max length, current length, buffer) - 0102 3ArFCs01 403 ld a,(column) - 0105 32rFCs01 404 ld (strtcol),a ;save start for ctl-x, ctl-h - 0108 2ArFCs01 405 ld hl,(info) - 010B 4E 406 ld c,(hl) - 010C 23 407 inc hl - 010D E5 408 push hl -a 010E 409 ld b,0 - 410 ;B = current buffer length, - 411 ;C = maximum buffer length, - 412 ;HL= next to fill - 1 - 010E 413 readnx: ;read next character, BC, HL active - 010E C5 414 push bc - 010F E5 415 push hl ;blen, cmax, HL saved - 0110 CDr5Bs00 416 readn0: call conin ;next char in A -q 0113 417 and 7fh ;mask parity bit - 0113 E1 418 pop hl - 0114 C1 419 pop bc ;reactivate counters -ua 0115 420 cp cr - 0115 CArBAs01 421 jp z,readen ;end of line? -ua 0118 422 cp lf - 0118 CArBAs01 423 jp z,readen ;also end of line -ua 011B 424 cp ctlh - 011B C2r2Ds01 425 jp nz,noth ;backspace? - 426 ;do we have any characters to back over? - 011E 78 427 ld a,b - 011F B7 428 or a - 0120 CAr0Es01 429 jp z,readnx - 430 ;characters remain in buffer, backup one - 0123 05 431 dec b ;remove one character - 0124 3ArFCs01 432 ld a,(column) - 0127 32rFCs01 433 ld (compcol),a ;col > 0 - 434 ;compcol > 0 marks repeat as length compute - 012A C3r73s01 435 jp linelen ;uses same code as repeat - 436 - 012D 437 noth: ;not a backspace -ua 012D 438 cp rubout - 012D C2r3Bs01 439 jp nz,notrub ;rubout char? - 440 ;rubout encountered, rubout if possible - 0130 78 441 ld a,b - 0131 B7 442 or a - 0132 CAr0Es01 443 jp z,readnx ;skip if len=0 - 444 ;buffer has characters, resend last char - 0135 7E 445 ld a,(hl) - 0136 05 446 dec b - 0137 2B 447 dec hl ;A = last char - 448 ;blen=blen-1, next to fill - 1 decremented - 0138 C3rA6s01 449 jp rdech1 ;act like this is an echo - 450 - 013B 451 notrub: ;not a rubout character, check end line -ua 013B 452 cp ctle - 013B C2r4As01 453 jp nz,note ;physical end line? - 454 ;yes, save active counters and force eol - 013E C5 455 push bc - 013F E5 456 push hl - 0140 CDrF0s00 457 call crlf - 0143 AF 458 xor a - 0144 32rFCs01 459 ld (strtcol),a ;start position = 00 - 0147 C3r10s01 460 jp readn0 ;for another character - 461 - 014A 462 note: ;not end of line, list toggle? -ua 014A 463 cp ctlp - 014A C2r54s01 464 jp nz,notp ;skip if not ctlp - 465 ;list toggle - change parity - 014D E5 466 push hl ;save next to fill - 1 -a 014E 467 ld hl,listcp ;HL=.listcp flag -a 014E 468 ld a,1 - 014E 96 469 sub (hl) ;True-listcp - 014F 77 470 ld (hl),a ;listcp = not listcp - 0150 E1 471 pop hl - 0151 C3r0Es01 472 jp readnx ;for another char - 473 - 0154 474 notp: ;not a ctlp, line delete? -ua 0154 475 cp ctlx - 0154 C2r66s01 476 jp nz,notx - 0157 E1 477 pop hl ;discard start position - 478 ;loop while column > strtcol - 0158 3ArFCs01 479 backx: ld a,(strtcol) -a 015B 480 ld hl,column - 015B BE 481 cp (hl) - 015C D2r02s01 482 jp nc,read ;start again - 015F 35 483 dec (hl) ;column = column - 1 - 0160 CDrD6s00 484 call backup ;one position - 0163 C3r58s01 485 jp backx - 486 - 0166 487 notx: ;not a control x, control u? - 488 ;not control-X, control-U? -ua 0166 489 cp ctlu - 0166 C2r70s01 490 jp nz,notu ;skip if not - 491 ;delete line (ctlu) - 0169 CDrDFs00 492 call crlfp ;physical eol - 016C E1 493 pop hl ;discard starting position - 016D C3r02s01 494 jp read ;to start all over - 495 - 0170 496 notu: ;not line delete, repeat line? -ua 0170 497 cp ctlr - 0170 C2rA3s01 498 jp nz,notr - 0173 499 linelen: ;repeat line, or compute line len (ctlh) - 500 ;if compcol > 0 - 0173 C5 501 push bc - 0174 CDrDFs00 502 call crlfp ;save line length - 0177 C1 503 pop bc - 0178 E1 504 pop hl - 0179 E5 505 push hl - 017A C5 506 push bc - 507 ;bcur, cmax active, beginning buff at HL - 017B 78 508 rep0: ld a,b - 017C B7 509 or a - 017D CAr8Ds01 510 jp z,rep1 ;count len to 00 - 0180 23 511 inc hl - 0181 4E 512 ld c,(hl) ;next to print - 0182 05 513 dec b - 0183 C5 514 push bc - 0184 E5 515 push hl ;count length down - 0185 CDrBBs00 516 call ctlout ;character echoed - 0188 E1 517 pop hl - 0189 C1 518 pop bc ;recall remaining count - 018A C3r7Bs01 519 jp rep0 ;for the next character - 520 - 018D 521 rep1: ;end of repeat, recall lengths - 522 ;original BC still remains pushed - 018D E5 523 push hl ;save next to fill - 018E 3ArFCs01 524 ld a,(compcol) - 0191 B7 525 or a ;>0 if computing length - 0192 CAr10s01 526 jp z,readn0 ;for another char if so - 527 ;column position computed for ctlh -a 0195 528 ld hl,column - 0195 96 529 sub (hl) ;diff > 0 - 0196 32rFCs01 530 ld (compcol),a ;count down below - 531 ;move back compcol-column spaces - 0199 532 backsp: ;move back one more space - 0199 CDrD6s00 533 call backup ;one space -a 019C 534 ld hl,compcol - 019C 35 535 dec (hl) - 019D C2r99s01 536 jp nz,backsp - 01A0 C3r10s01 537 jp readn0 ;for next character - 538 - 01A3 539 notr: ;not a ctlr, place into buffer - 01A3 23 540 rdecho: inc hl - 01A4 77 541 ld (hl),a ;character filled to mem - 01A5 04 542 inc b ;blen = blen + 1 - 01A6 543 rdech1: ;look for a random control character - 01A6 C5 544 push bc - 01A7 E5 545 push hl ;active values saved - 01A8 4F 546 ld c,a ;ready to print - 01A9 CDrBBs00 547 call ctlout ;may be up-arrow C - 01AC E1 548 pop hl - 01AD C1 549 pop bc - 01AE 7E 550 ld a,(hl) ;recall char -ua 01AF 551 cp ctlc ;set flags for reboot test - 01AF 78 552 ld a,b ;move length to A - 01B0 C2rB6s01 553 jp nz,notc ;skip if not a control c -a 01B3 554 cp 1 ;control C, must be length 1 -u 01B3 CA 00 00 555 jp z,reboot ;reboot if blen = 1 - 556 ;length not one, so skip reboot - 01B6 557 notc: ;not reboot, are we at end of buffer? - 01B6 B9 558 cp c - 01B7 DAr0Es01 559 jp c,readnx ;go for another if not - 01BA 560 readen: ;end of read operation, store blen - 01BA E1 561 pop hl - 01BB 70 562 ld (hl),b ;M(current len) = B -ua 01BC 563 ld c,cr - 01BC C3r91s00 564 jp conout ;return carriage - 565 ; ret - 01BF 566 func1: ;return console character with echo - 01BF CDr61s00 567 call conech - 01C2 C3rF5s01 568 jp sta$ret - 569 -o 01C5 570 func2 equ tabout - 571 ;write console character with tab expansion - 572 - 01C5 573 func3: ;return reader character -u 01C5 CD 00 00 574 call readerf - 01C8 C3rF5s01 575 jp sta$ret - 576 - 577 ;func4: equated to punchf - 578 ;write punch character - 579 - 580 ;func5: equated to listf - 581 ;write list character - 582 ;write to list device - 583 - 01CB 584 func6: ;direct console i/o - read if 0ffh - 01CB 79 585 ld a,c - 01CC 3C 586 inc a - 01CD CArD7s01 587 jp z,dirinp ;0ffh => 00h, means input mode - 01D0 3C 588 inc a -u 01D1 CA 00 00 589 jp z,constf ;0feH in C for status - 590 ;direct output function -u 01D4 C3 00 00 591 jp conoutf - 592 -u 01D7 CD 00 00 593 dirinp: call constf ;status check - 01DA B7 594 or a - 01DB CArAFs0A 595 jp z,retmon ;skip, return 00 if not ready - 596 ;character is ready, get it -u 01DE CD 00 00 597 call coninf ;to A - 01E1 C3rF5s01 598 jp sta$ret - 599 - 01E4 600 func7: ;return io byte -u 01E4 3A 00 00 601 ld a,(ioloc) - 01E7 C3rF5s01 602 jp sta$ret - 603 - 01EA 604 func8: ;set i/o byte -ua 01EA 605 ld hl,ioloc - 01EA 71 606 ld (hl),c - 01EB C9 607 ret ;jmp goback - 608 - 01EC 609 func9: ;write line until $ encountered - 01EC EB 610 ex de,hl ;was lhld info - 01ED 4D 611 ld c,l - 01EE 44 612 ld b,h ;BC=string address - 01EF C3rF6s00 613 jp print ;out to console - 614 -o 01F2 615 func10 equ read - 616 ;read a buffered console line - 617 - 01F2 618 func11: ;check console status - 01F2 CDr74s00 619 call conbrk - 620 ;(drop through to sta$ret) - 01F5 621 sta$ret: ;store the A register to aret - 01F5 32rFCs01 622 ld (aret),a - 01F8 623 func$ret: - 01F8 C9 624 ret ;jmp goback (pop stack for non cp/m functions) - 625 - 01F9 626 setlret1: ;set lret = 1 -a 01F9 627 ld a,1 - 01F9 C3rF5s01 628 jp sta$ret - 629 - 630 - 631 - 632 ; data areas - 633 - 01FC 634 compcol: -o 01FC 635 db 0 ;true if computing column position - 01FC 636 strtcol: -o 01FC 637 db 0 ;starting column position after read -o 01FC 638 column: db 0 ;column position -o 01FC 639 listcp: db 0 ;listing toggle -o 01FC 640 kbchar: db 0 ;initial key char = 00 -o 01FC 641 entsp: ds 2 ;entry stack pointer -o 01FC 642 ds ssize*2 ;stack size - 01FC 643 lstack: - 644 ; end of Basic I/O System - 645 - 646 ;***************************************************************** - 647 ;***************************************************************** - 648 - 649 ; common values shared between bdosi and bdos - 01FC 650 usrcode: -o 01FC 651 db 0 ;current user number -o 01FC 652 curdsk: db 0 ;current disk number -o 01FC 653 info: ds 2 ;information address -o 01FC 654 aret: ds 2 ;address value to return -o 01FC 655 lret equ aret ;low(aret) - 656 - 657 ;***************************************************************** - 658 ;***************************************************************** - 659 ;** ** - 660 ;** B a s i c D i s k O p e r a t i n g S y s t e m ** - 661 ;** ** - 662 ;***************************************************************** - 663 ;***************************************************************** - 664 -o 01FC 665 dvers equ 22h ;version 2.2 - 666 ; module addresses - 667 - 668 ; literal constants -o 01FC 669 true equ 0ffh ;constant true -o 01FC 670 false equ 000h ;constant false -o 01FC 671 enddir equ 0ffffh ;end of directory -o 01FC 672 byte equ 1 ;number of bytes for "byte" type -o 01FC 673 word equ 2 ;number of bytes for "word" type - 674 - 675 ; fixed addresses in low memory -o 01FC 676 tfcb equ 005ch ;default fcb location -o 01FC 677 tbuff equ 0080h ;default buffer location - 678 - 679 ; fixed addresses referenced in bios module are - 680 ; pererr (0009), selerr (000c), roderr (000f) - 681 - 682 ; error message handlers - 683 - 684 ;per$error: ;report permanent error to user - 685 ; ld hl,pererr - 686 ; jp goerr - 687 - 688 ;rod$error: ;report read/only disk error - 689 ; ld hl,roderr - 690 ; jp goerr - 691 - 692 ;rof$error: ;report read/only file error - 693 ; ld hl,roferr - 694 ; jp goerr - 695 - 01FC 696 sel$error: ;report select error -a 01FC 697 ld hl,selerr - 698 - 699 - 01FC 700 goerr: ;HL = .errorhandler, call subroutine - 01FC 5E 701 ld e,(hl) - 01FD 23 702 inc hl - 01FE 56 703 ld d,(hl) ;address of routine in DE - 01FF EB 704 ex de,hl - 0200 E9 705 jp (hl) ;to subroutine - 706 - 707 - 708 - 709 ; local subroutines for bios interface - 710 - 0201 711 move: ;move data length of length C from source DE to - 712 ;destination given by HL - 0201 0C 713 inc c ;in case it is zero - 0202 0D 714 move0: dec c - 0203 C8 715 ret z ;more to move - 0204 1A 716 ld a,(de) - 0205 77 717 ld (hl),a ;one byte moved - 0206 13 718 inc de - 0207 23 719 inc hl ;to next byte - 0208 C3r02s02 720 jp move0 - 721 - 020B 722 selectdisk: ;select the disk drive given by curdsk, and fill - 723 ;the base addresses curtrka - alloca, then fill - 724 ;the values of the disk parameter block - 020B 3ArFCs01 725 ld a,(curdsk) - 020E 4F 726 ld c,a ;current disk# to c - 727 ;lsb of e = 0 if not yet logged - in -u 020F CD 00 00 728 call seldskf ;HL filled by call - 729 ;HL = 0000 if error, otherwise disk headers - 0212 7C 730 ld a,h - 0213 B5 731 or l - 0214 C8 732 ret z ;return with 0000 in HL and z flag - 733 ;disk header block address in hl - 0215 5E 734 ld e,(hl) - 0216 23 735 inc hl - 0217 56 736 ld d,(hl) - 0218 23 737 inc hl ;DE=.tran - 0219 22rC6s0A 738 ld (cdrmaxa),hl - 021C 23 739 inc hl - 021D 23 740 inc hl ;.cdrmax - 021E 22rC6s0A 741 ld (curtrka),hl - 0221 23 742 inc hl - 0222 23 743 inc hl ;HL=.currec - 0223 22rC6s0A 744 ld (curreca),hl - 0226 23 745 inc hl - 0227 23 746 inc hl ;HL=.buffa - 747 ;DE still contains .tran - 0228 EB 748 ex de,hl - 0229 22rC6s0A 749 ld (tranv),hl ;.tran vector -a 022C 750 ld hl,buffa ;DE= source for move, HL=dest -ua 022C 751 ld c,addlist - 022C CDr01s02 752 call move ;addlist filled - 753 ;now fill the disk parameter block - 022F 2ArC6s0A 754 ld hl,(dpbaddr) - 0232 EB 755 ex de,hl ;DE is source -a 0233 756 ld hl,sectpt ;HL is destination -ua 0233 757 ld c,dpblist - 0233 CDr01s02 758 call move ;data filled - 759 ;now set single/double map mode - 0236 2ArC6s0A 760 ld hl,(maxall) ;largest allocation number - 0239 7C 761 ld a,h ;00 indicates < 255 -a 023A 762 ld hl,single -ua 023A 763 ld (hl),true ;assume a=00 - 023A B7 764 or a - 023B CAr3Es02 765 jp z,retselect - 766 ;high order of maxall not zero, use double dm -ua 023E 767 ld (hl),false - 023E 768 retselect: -ua 023E 769 ld a,true - 023E B7 770 or a - 023F C9 771 ret ;select disk function ok - 772 - 0240 773 home: ;move to home position, then offset to start of dir -u 0240 CD 00 00 774 call homef ;move to track 00, sector 00 reference - 775 ;lxi h,offset ;mov c,m ;inx h ;mov b,m ;call settrkf - 776 ;first directory position selected - 0243 AF 777 xor a ;constant zero to accumulator - 0244 2ArC6s0A 778 ld hl,(curtrka) - 0247 77 779 ld (hl),a - 0248 23 780 inc hl - 0249 77 781 ld (hl),a ;curtrk=0000 - 024A 2ArC6s0A 782 ld hl,(curreca) - 024D 77 783 ld (hl),a - 024E 23 784 inc hl - 024F 77 785 ld (hl),a ;currec=0000 - 786 ;curtrk, currec both set to 0000 - 0250 C9 787 ret - 788 - 0251 789 rdbuff: ;read buffer and check condition -u 0251 CD 00 00 790 call readf ;current drive, track, sector, dma - 0254 C3r5As02 791 jp diocomp ;check for i/o errors - 792 - 0257 793 wrbuff: ;write buffer and check condition - 794 ;write type (wrtype) is in register C - 795 ;wrtype = 0 => normal write operation - 796 ;wrtype = 1 => directory write operation - 797 ;wrtype = 2 => start of new block -u 0257 CD 00 00 798 call writef ;current drive, track, sector, dma - 025A 799 diocomp: ;check for disk errors - 025A B7 800 or a - 025B C8 801 ret z -a 025C 802 ld hl,pererr - 025C C3rFCs01 803 jp goerr - 804 - 025F 805 seek$dir: ;seek the record containing the current dir entry - 025F 2ArC6s0A 806 ld hl,(dcnt) ;directory counter to HL -ua 0262 807 ld c,dskshf - 0262 CDr6As03 808 call hlrotr ;value to HL - 0265 22rC6s0A 809 ld (arecord),hl - 0268 22rC6s0A 810 ld (drec),hl ;ready for seek - 811 ; jp seek - 812 ; ret - 813 - 814 - 026B 815 seek: ;seek the track given by arecord (actual record) - 816 ;local equates for registers - 817 ;load the registers from memory -a 026B 818 ld hl,arecord - 026B 4E 819 ld c,(hl) - 026C 23 820 inc hl - 026D 46 821 ld b,(hl) - 026E 2ArC6s0A 822 ld hl,(curreca) - 0271 5E 823 ld e,(hl) - 0272 23 824 inc hl - 0273 56 825 ld d,(hl) - 0274 2ArC6s0A 826 ld hl,(curtrka) - 0277 7E 827 ld a,(hl) - 0278 23 828 inc hl - 0279 66 829 ld h,(hl) - 027A 6F 830 ld l,a - 831 ;loop while arecord < currec - 027B 79 832 seek0: ld a,c - 027C 93 833 sub e - 027D 78 834 ld a,b - 027E 9A 835 sbc a,d - 027F D2r91s02 836 jp nc,seek1 ;skip if arecord >= currec - 837 ;currec = currec - sectpt - 0282 E5 838 push hl - 0283 2ArC6s0A 839 ld hl,(sectpt) - 0286 7B 840 ld a,e - 0287 95 841 sub l - 0288 5F 842 ld e,a - 0289 7A 843 ld a,d - 028A 9C 844 sbc a,h - 028B 57 845 ld d,a - 028C E1 846 pop hl - 847 ;curtrk = curtrk - 1 - 028D 2B 848 dec hl - 028E C3r7Bs02 849 jp seek0 ;for another try - 850 - 0291 851 seek1: ;look while arecord >= (t:=currec + sectpt) - 0291 E5 852 push hl - 0292 2ArC6s0A 853 ld hl,(sectpt) - 0295 19 854 add hl,de ;HL = currec+sectpt - 0296 DArA6s02 855 jp c,seek2 ;can be > FFFFH - 0299 79 856 ld a,c - 029A 95 857 sub l - 029B 78 858 ld a,b - 029C 9C 859 sbc a,h - 029D DArA6s02 860 jp c,seek2 ;skip if t > arecord - 861 ;currec = t - 02A0 EB 862 ex de,hl - 863 ;curtrk = curtrk + 1 - 02A1 E1 864 pop hl - 02A2 23 865 inc hl - 02A3 C3r91s02 866 jp seek1 ;for another try - 867 - 02A6 E1 868 seek2: pop hl - 869 ;arrive here with updated values in each register - 02A7 C5 870 push bc - 02A8 D5 871 push de - 02A9 E5 872 push hl ;to stack for later - 873 ;stack contains (lowest) BC=arecord, DE=currec, HL=curtrk - 02AA EB 874 ex de,hl - 02AB 2ArC6s0A 875 ld hl,(offset) - 02AE 19 876 add hl,de ;HL = curtrk+offset - 02AF 44 877 ld b,h - 02B0 4D 878 ld c,l -u 02B1 CD 00 00 879 call settrkf ;track set up - 880 ;note that BC - curtrk is difference to move in bios - 02B4 D1 881 pop de ;recall curtrk - 02B5 2ArC6s0A 882 ld hl,(curtrka) - 02B8 73 883 ld (hl),e - 02B9 23 884 inc hl - 02BA 72 885 ld (hl),d ;curtrk updated - 886 ;now compute sector as arecord-currec - 02BB D1 887 pop de ;recall currec - 02BC 2ArC6s0A 888 ld hl,(curreca) - 02BF 73 889 ld (hl),e - 02C0 23 890 inc hl - 02C1 72 891 ld (hl),d - 02C2 C1 892 pop bc ;BC=arecord, DE=currec - 02C3 79 893 ld a,c - 02C4 93 894 sub e - 02C5 4F 895 ld c,a - 02C6 78 896 ld a,b - 02C7 9A 897 sbc a,d - 02C8 47 898 ld b,a - 02C9 2ArC6s0A 899 ld hl,(tranv) - 02CC EB 900 ex de,hl ;BC=sector#, DE=.tran -u 02CD CD 00 00 901 call sectran ;HL = tran(sector) - 02D0 4D 902 ld c,l - 02D1 44 903 ld b,h ;BC = tran(sector) -u 02D2 C3 00 00 904 jp setsecf ;sector selected - 905 ; ret - 906 - 907 ; file control block (fcb) constants -o 02D5 908 empty equ 0e5h ;empty directory entry -o 02D5 909 lstrec equ 127 ;last record# in extent -o 02D5 910 recsiz equ 128 ;record size -o 02D5 911 fcblen equ 32 ;file control block size -o 02D5 912 dirrec equ recsiz/fcblen ;directory elts / record -o 02D5 913 dskshf equ 2 ;log2(dirrec) -o 02D5 914 dskmsk equ dirrec-1 -o 02D5 915 fcbshf equ 5 ;log2(fcblen) - 916 -o 02D5 917 extnum equ 12 ;extent number field -o 02D5 918 maxext equ 31 ;largest extent number -o 02D5 919 ubytes equ 13 ;unfilled bytes field -o 02D5 920 modnum equ 14 ;data module number -o 02D5 921 maxmod equ 15 ;largest module number -o 02D5 922 fwfmsk equ 80h ;file write flag is high order modnum -o 02D5 923 namlen equ 15 ;name length -o 02D5 924 reccnt equ 15 ;record count field -o 02D5 925 dskmap equ 16 ;disk map field -o 02D5 926 lstfcb equ fcblen-1 -o 02D5 927 nxtrec equ fcblen -o 02D5 928 ranrec equ nxtrec+1 ;random record field (2 bytes) - 929 - 930 ; reserved file indicators -o 02D5 931 rofile equ 9 ;high order of first type char -o 02D5 932 invis equ 10 ;invisible file in dir command - 933 ; equ 11 ;reserved - 934 - 935 ; utility functions for file access - 936 - 02D5 937 dm$position: ;compute disk map position for vrecord to HL -a 02D5 938 ld hl,blkshf - 02D5 4E 939 ld c,(hl) ;shift count to C - 02D6 3ArC6s0A 940 ld a,(vrecord) ;current virtual record to A - 02D9 B7 941 dmpos0: or a - 02DA 1F 942 rra - 02DB 0D 943 dec c - 02DC C2rD9s02 944 jp nz,dmpos0 - 945 ;A = shr(vrecord,blkshf) = vrecord/2**(sect/block) - 02DF 47 946 ld b,a ;save it for later addition -a 02E0 947 ld a,8 - 02E0 96 948 sub (hl) ;8-blkshf to accumulator - 02E1 4F 949 ld c,a ;extent shift count in register c - 02E2 3ArC6s0A 950 ld a,(extval) ;extent value ani extmsk - 02E5 951 dmpos1: - 952 ;blkshf = 3,4,5,6,7, C=5,4,3,2,1 - 953 ;shift is 4,3,2,1,0 - 02E5 0D 954 dec c - 02E6 CArEEs02 955 jp z,dmpos2 - 02E9 B7 956 or a - 02EA 17 957 rla - 02EB C3rE5s02 958 jp dmpos1 - 959 - 02EE 960 dmpos2: ;arrive here with A = shl(ext and extmsk,7-blkshf) - 02EE 80 961 add a,b ;add the previous shr(vrecord,blkshf) value - 962 ;A is one of the following values, depending upon alloc - 963 ;bks blkshf - 964 ;1k 3 v/8 + extval * 16 - 965 ;2k 4 v/16+ extval * 8 - 966 ;4k 5 v/32+ extval * 4 - 967 ;8k 6 v/64+ extval * 2 - 968 ;16k 7 v/128+extval * 1 - 02EF C9 969 ret ;with dm$position in A - 970 - 02F0 971 getdm: ;return disk map value from position given by BC - 02F0 2ArFCs01 972 ld hl,(info) ;base address of file control block -ua 02F3 973 ld de,dskmap - 02F3 19 974 add hl,de ;HL =.diskmap - 02F4 09 975 add hl,bc ;index by a single byte value - 02F5 3ArC6s0A 976 ld a,(single) ;single byte/map entry? - 02F8 B7 977 or a - 02F9 CArFEs02 978 jp z,getdmd ;get disk map single byte - 02FC 6E 979 ld l,(hl) -a 02FD 980 ld h,0 - 02FD C9 981 ret ;with HL=00bb - 02FE 982 getdmd: - 02FE 09 983 add hl,bc ;HL=.fcb(dm+i*2) - 984 ;double precision value returned - 02FF 5E 985 ld e,(hl) - 0300 23 986 inc hl - 0301 56 987 ld d,(hl) - 0302 EB 988 ex de,hl - 0303 C9 989 ret - 990 - 0304 991 index: ;compute disk block number from current fcb - 0304 CDrD5s02 992 call dm$position ;0...15 in register A - 0307 4F 993 ld c,a -a 0308 994 ld b,0 - 0308 CDrF0s02 995 call getdm ;value to HL - 030B 22rC6s0A 996 ld (arecord),hl - 030E C9 997 ret - 998 - 030F 999 allocated: ;called following index to see if block allocated - 030F 2ArC6s0A 1000 ld hl,(arecord) - 0312 7D 1001 ld a,l - 0313 B4 1002 or h - 0314 C9 1003 ret - 1004 - 0315 1005 atran: ;compute actual record address, assuming index called - 0315 3ArC6s0A 1006 ld a,(blkshf) ;shift count to reg A - 0318 2ArC6s0A 1007 ld hl,(arecord) - 031B 29 1008 atran0: add hl,hl - 031C 3D 1009 dec a - 031D C2r1Bs03 1010 jp nz,atran0 ;shl(arecord,blkshf) - 0320 22rC6s0A 1011 ld (arecord1),hl ;save shifted block # - 0323 3ArC6s0A 1012 ld a,(blkmsk) - 0326 4F 1013 ld c,a ;mask value to C - 0327 3ArC6s0A 1014 ld a,(vrecord) - 032A A1 1015 and c ;masked value in A - 032B B5 1016 or l - 032C 6F 1017 ld l,a ;to HL - 032D 22rC6s0A 1018 ld (arecord),hl ;arecord=HL or (vrecord and blkmsk) - 0330 C9 1019 ret - 1020 - 0331 1021 getexta: ;get current extent field address to A - 0331 2ArFCs01 1022 ld hl,(info) -ua 0334 1023 ld de,extnum - 0334 19 1024 add hl,de ;HL=.fcb(extnum) - 0335 C9 1025 ret - 1026 - 0336 1027 getfcba: ;compute reccnt and nxtrec addresses for get/setfcb - 0336 2ArFCs01 1028 ld hl,(info) -ua 0339 1029 ld de,reccnt - 0339 19 1030 add hl,de - 033A EB 1031 ex de,hl ;DE=.fcb(reccnt) -ua 033B 1032 ld hl,nxtrec-reccnt - 033B 19 1033 add hl,de ;HL=.fcb(nxtrec) - 033C C9 1034 ret - 1035 - 033D 1036 getfcb: ;set variables from currently addressed fcb - 033D CDr36s03 1037 call getfcba ;addresses in DE, HL - 0340 7E 1038 ld a,(hl) - 0341 32rC6s0A 1039 ld (vrecord),a ;vrecord=fcb(nxtrec) - 0344 EB 1040 ex de,hl - 0345 7E 1041 ld a,(hl) - 0346 32rC6s0A 1042 ld (rcount),a ;rcount=fcb(reccnt) - 0349 CDr31s03 1043 call getexta ;HL=.fcb(extnum) - 034C 3ArC6s0A 1044 ld a,(extmsk) ;extent mask to a - 034F A6 1045 and (hl) ;fcb(extnum) and extmsk - 0350 32rC6s0A 1046 ld (extval),a - 0353 C9 1047 ret - 1048 - 0354 1049 setfcb: ;place values back into current fcb - 0354 CDr36s03 1050 call getfcba ;addresses to DE, HL - 0357 3ArC6s0A 1051 ld a,(seqio) -a 035A 1052 cp 02 - 035A C2r5Es03 1053 jp nz,setfcb1 - 035D AF 1054 xor a ;check ranfill - 035E 1055 setfcb1: - 035E 4F 1056 ld c,a ;=1 if sequential i/o - 035F 3ArC6s0A 1057 ld a,(vrecord) - 0362 81 1058 add a,c - 0363 77 1059 ld (hl),a ;fcb(nxtrec)=vrecord+seqio - 0364 EB 1060 ex de,hl - 0365 3ArC6s0A 1061 ld a,(rcount) - 0368 77 1062 ld (hl),a ;fcb(reccnt)=rcount - 0369 C9 1063 ret - 1064 - 036A 1065 hlrotr: ;hl rotate right by amount C - 036A 0C 1066 inc c ;in case zero - 036B 1067 hlrotr0: - 036B 0D 1068 dec c - 036C C8 1069 ret z ;return when zero - 036D 7C 1070 ld a,h - 036E B7 1071 or a - 036F 1F 1072 rra - 0370 67 1073 ld h,a ;high byte - 0371 7D 1074 ld a,l - 0372 1F 1075 rra - 0373 6F 1076 ld l,a ;low byte - 0374 C3r6Bs03 1077 jp hlrotr0 - 1078 - 0377 1079 compute$cs: ;compute checksum for current directory buffer -ua 0377 1080 ld c,recsiz ;size of directory buffer - 0377 2ArC6s0A 1081 ld hl,(buffa) ;current directory buffer - 037A AF 1082 xor a ;clear checksum value - 037B 1083 computecs0: - 037B 86 1084 add a,(hl) - 037C 23 1085 inc hl - 037D 0D 1086 dec c ;cs=cs+buff(recsiz-C) - 037E C2r7Bs03 1087 jp nz,computecs0 - 0381 C9 1088 ret ;with checksum in A - 1089 - 0382 1090 hlrotl: ;rotate the mask in HL by amount in C - 0382 0C 1091 inc c ;may be zero - 0383 1092 hlrotl0: - 0383 0D 1093 dec c - 0384 C8 1094 ret z ;return if zero - 0385 29 1095 add hl,hl - 0386 C3r83s03 1096 jp hlrotl0 - 1097 - 0389 1098 set$cdisk: ;set a "1" value in curdsk position of BC - 0389 C5 1099 push bc ;save input parameter - 038A 3ArFCs01 1100 ld a,(curdsk) - 038D 4F 1101 ld c,a ;ready parameter for shift -a 038E 1102 ld hl,1 ;number to shift - 038E CDr82s03 1103 call hlrotl ;HL = mask to integrate - 0391 C1 1104 pop bc ;original mask - 0392 79 1105 ld a,c - 0393 B5 1106 or l - 0394 6F 1107 ld l,a - 0395 78 1108 ld a,b - 0396 B4 1109 or h - 0397 67 1110 ld h,a ;HL = mask or rol(1,curdsk) - 0398 C9 1111 ret - 1112 - 0399 1113 nowrite: ;return true if dir checksum difference occurred - 0399 2ArC6s0A 1114 ld hl,(rodsk) - 039C 3ArFCs01 1115 ld a,(curdsk) - 039F 4F 1116 ld c,a - 03A0 CDr6As03 1117 call hlrotr - 03A3 7D 1118 ld a,l -q 03A4 1119 and 1b - 03A4 C9 1120 ret ;non zero if nowrite - 1121 - 03A5 1122 set$ro: ;set current disk to read only -a 03A5 1123 ld hl,rodsk - 03A5 4E 1124 ld c,(hl) - 03A6 23 1125 inc hl - 03A7 46 1126 ld b,(hl) - 03A8 CDr89s03 1127 call set$cdisk ;sets bit to 1 - 03AB 22rC6s0A 1128 ld (rodsk),hl - 1129 ;high water mark in directory goes to max - 03AE 2ArC6s0A 1130 ld hl,(dirmax) - 03B1 23 1131 inc hl - 03B2 EB 1132 ex de,hl ;DE = directory max - 03B3 2ArC6s0A 1133 ld hl,(cdrmaxa) ;HL = .cdrmax - 03B6 73 1134 ld (hl),e - 03B7 23 1135 inc hl - 03B8 72 1136 ld (hl),d ;cdrmax = dirmax - 03B9 C9 1137 ret - 1138 - 03BA 1139 check$rodir: ;check current directory element for read/only status - 03BA CDrCBs03 1140 call getdptra ;address of element - 1141 - 03BD 1142 check$rofile: ;check current buff(dptr) or fcb(0) for r/o status -ua 03BD 1143 ld de,rofile - 03BD 19 1144 add hl,de ;offset to ro bit - 03BE 7E 1145 ld a,(hl) - 03BF 17 1146 rla - 03C0 D0 1147 ret nc ;return if not set -a 03C1 1148 ld hl,roferr - 03C1 C3rFCs01 1149 jp goerr - 1150 ; jp rof$error ;exit to read only disk message - 1151 - 1152 - 03C4 1153 check$write: ;check for write protected disk - 03C4 CDr99s03 1154 call nowrite - 03C7 C8 1155 ret z ;ok to write if not rodsk -a 03C8 1156 ld hl,roderr - 03C8 C3rFCs01 1157 jp goerr - 1158 ; jp rod$error ;read only disk error - 1159 - 03CB 1160 getdptra: ;compute the address of a directory element at - 1161 ;positon dptr in the buffer - 03CB 2ArC6s0A 1162 ld hl,(buffa) - 03CE 3ArC6s0A 1163 ld a,(dptr) - 03D1 1164 addh: ;HL = HL + A - 03D1 85 1165 add a,l - 03D2 6F 1166 ld l,a - 03D3 D0 1167 ret nc - 1168 ;overflow to H - 03D4 24 1169 inc h - 03D5 C9 1170 ret - 1171 - 1172 - 03D6 1173 getmodnum: ;compute the address of the module number - 1174 ;bring module number to accumulator - 1175 ;(high order bit is fwf (file write flag) - 03D6 2ArFCs01 1176 ld hl,(info) -ua 03D9 1177 ld de,modnum - 03D9 19 1178 add hl,de ;HL=.fcb(modnum) - 03DA 7E 1179 ld a,(hl) - 03DB C9 1180 ret ;A=fcb(modnum) - 1181 - 03DC 1182 clrmodnum: ;clear the module number field for user open/make - 03DC CDrD6s03 1183 call getmodnum -a 03DF 1184 ld (hl),0 ;fcb(modnum)=0 - 03DF C9 1185 ret - 1186 - 03E0 CDrD6s03 1187 setfwf: call getmodnum ;HL=.fcb(modnum), A=fcb(modnum) - 1188 ;set fwf (file write flag) to "1" -ua 03E3 1189 or fwfmsk - 03E3 77 1190 ld (hl),a ;fcb(modnum)=fcb(modnum) or 80h - 1191 ;also returns non zero in accumulator - 03E4 C9 1192 ret - 1193 - 1194 - 03E5 1195 compcdr: ;return cy if cdrmax > dcnt - 03E5 2ArC6s0A 1196 ld hl,(dcnt) - 03E8 EB 1197 ex de,hl ;DE = directory counter - 03E9 2ArC6s0A 1198 ld hl,(cdrmaxa) ;HL=.cdrmax - 03EC 7B 1199 ld a,e - 03ED 96 1200 sub (hl) ;low(dcnt) - low(cdrmax) - 03EE 23 1201 inc hl ;HL = .cdrmax+1 - 03EF 7A 1202 ld a,d - 03F0 9E 1203 sbc a,(hl) ;hig(dcnt) - hig(cdrmax) - 1204 ;condition dcnt - cdrmax produces cy if cdrmax>dcnt - 03F1 C9 1205 ret - 1206 - 03F2 1207 setcdr: ;if not (cdrmax > dcnt) then cdrmax = dcnt+1 - 03F2 CDrE5s03 1208 call compcdr - 03F5 D8 1209 ret c ;return if cdrmax > dcnt - 1210 ;otherwise, HL = .cdrmax+1, DE = dcnt - 03F6 13 1211 inc de - 03F7 72 1212 ld (hl),d - 03F8 2B 1213 dec hl - 03F9 73 1214 ld (hl),e - 03FA C9 1215 ret - 1216 - 03FB 1217 subdh: ;compute HL = DE - HL - 03FB 7B 1218 ld a,e - 03FC 95 1219 sub l - 03FD 6F 1220 ld l,a - 03FE 7A 1221 ld a,d - 03FF 9C 1222 sbc a,h - 0400 67 1223 ld h,a - 0401 C9 1224 ret - 1225 - 0402 1226 newchecksum: -ua 0402 1227 ld c,true ;drop through to compute new checksum - 0402 1228 checksum: ;compute current checksum record and update the - 1229 ;directory element if C=true, or check for = if not - 1230 ;drec < chksiz? - 0402 2ArC6s0A 1231 ld hl,(drec) - 0405 EB 1232 ex de,hl - 0406 2ArC6s0A 1233 ld hl,(chksiz) - 0409 CDrFBs03 1234 call subdh ;DE-HL - 040C D0 1235 ret nc ;skip checksum if past checksum vector size - 1236 ;drec < chksiz, so continue - 040D C5 1237 push bc ;save init flag - 040E CDr77s03 1238 call compute$cs ;check sum value to A - 0411 2ArC6s0A 1239 ld hl,(checka) ;address of check sum vector - 0414 EB 1240 ex de,hl - 0415 2ArC6s0A 1241 ld hl,(drec) ;value of drec - 0418 19 1242 add hl,de ;HL = .check(drec) - 0419 C1 1243 pop bc ;recall true=0ffh or false=00 to C - 041A 0C 1244 inc c ;0ffh produces zero flag - 041B CAr28s04 1245 jp z,initial$cs - 1246 ;not initializing, compare - 041E BE 1247 cp (hl) ;compute$cs=check(drec)? - 041F C8 1248 ret z ;no message if ok - 1249 ;checksum error, are we beyond - 1250 ;the end of the disk? - 0420 CDrE5s03 1251 call compcdr - 0423 D0 1252 ret nc ;no message if so - 0424 CDrA5s03 1253 call set$ro ;read/only disk set - 0427 C9 1254 ret - 1255 - 0428 1256 initial$cs: ;initializing the checksum - 0428 77 1257 ld (hl),a - 0429 C9 1258 ret - 1259 - 1260 - 042A 1261 wrdir: ;write the current directory entry, set checksum - 042A CDr02s04 1262 call newchecksum ;initialize entry - 042D CDr3Fs04 1263 call setdir ;directory dma -a 0430 1264 ld c,1 ;indicates a write directory operation - 0430 CDr57s02 1265 call wrbuff ;write the buffer - 0433 C3r3Cs04 1266 jp setdata ;to data dma address - 1267 ; ret - 0436 1268 rd$dir: ;read a directory entry into the directory buffer - 0436 CDr3Fs04 1269 call setdir ;directory dma - 0439 CDr51s02 1270 call rdbuff ;directory record loaded - 1271 ;jmp setdata to data dma address - 1272 ; ret - 043C 1273 setdata: ;set data dma address -a 043C 1274 ld hl,dmaad - 043C C3r3Fs04 1275 jp setdma ;to complete the call - 1276 - 043F 1277 setdir: ;set directory dma address -a 043F 1278 ld hl,buffa ;jmp setdma to complete call - 1279 - 043F 1280 setdma: ;HL=.dma address to set (i.e., buffa or dmaad) - 043F 4E 1281 ld c,(hl) - 0440 23 1282 inc hl - 0441 46 1283 ld b,(hl) ;parameter ready -u 0442 C3 00 00 1284 jp setdmaf - 1285 - 0445 1286 dir$to$user: ;copy the directory entry to the user buffer - 1287 ;after call to search or searchn by user code - 0445 2ArC6s0A 1288 ld hl,(buffa) - 0448 EB 1289 ex de,hl ;source is directory buffer - 0449 2ArC6s0A 1290 ld hl,(dmaad) ;destination is user dma address -ua 044C 1291 ld c,recsiz ;copy entire record - 044C C3r01s02 1292 jp move - 1293 ; ret - 1294 - 044F 1295 end$of$dir: ;return zero flag if at end of directory, non zero - 1296 ;if not at end (end of dir if dcnt = 0ffffh) -a 044F 1297 ld hl,dcnt - 044F 7E 1298 ld a,(hl) ;may be 0ffh - 0450 23 1299 inc hl - 0451 BE 1300 cp (hl) ;low(dcnt) = high(dcnt)? - 0452 C0 1301 ret nz ;non zero returned if different - 1302 ;high and low the same, = 0ffh? - 0453 3C 1303 inc a ;0ffh becomes 00 if so - 0454 C9 1304 ret - 1305 - 0455 1306 set$end$dir: ;set dcnt to the end of the directory -ua 0455 1307 ld hl,enddir - 0455 22rC6s0A 1308 ld (dcnt),hl - 0458 C9 1309 ret - 1310 - 0459 1311 read$dir: ;read next directory entry, with C=true if initializing - 0459 2ArC6s0A 1312 ld hl,(dirmax) - 045C EB 1313 ex de,hl ;in preparation for subtract - 045D 2ArC6s0A 1314 ld hl,(dcnt) - 0460 23 1315 inc hl - 0461 22rC6s0A 1316 ld (dcnt),hl ;dcnt=dcnt+1 - 1317 ;continue while dirmax >= dcnt (dirmax-dcnt no cy) - 0464 CDrFBs03 1318 call subdh ;DE-HL - 0467 D2r6Ds04 1319 jp nc,read$dir0 - 1320 ;yes, set dcnt to end of directory - 046A C3r55s04 1321 jp set$end$dir - 1322 ; ret - 1323 - 046D 1324 read$dir0: ;not at end of directory, seek next element - 1325 ;initialization flag is in C - 046D 3ArC6s0A 1326 ld a,(dcnt) -ua 0470 1327 and dskmsk ;low(dcnt) and dskmsk -ua 0470 1328 ld b,fcbshf ;to multiply by fcb size - 0470 1329 read$dir1: - 0470 87 1330 add a,a - 0471 05 1331 dec b - 0472 C2r70s04 1332 jp nz,read$dir1 - 1333 ;A = (low(dcnt) and dskmsk) shl fcbshf - 0475 32rC6s0A 1334 ld (dptr),a ;ready for next dir operation - 0478 B7 1335 or a - 0479 C0 1336 ret nz ;return if not a new record - 047A C5 1337 push bc ;save initialization flag C - 047B CDr5Fs02 1338 call seek$dir ;seek proper record - 047E CDr36s04 1339 call rd$dir ;read the directory record - 0481 C1 1340 pop bc ;recall initialization flag - 0482 C3r02s04 1341 jp checksum ;checksum the directory elt - 1342 ; ret - 1343 - 1344 - 0485 1345 getallocbit: ;given allocation vector position BC, return with byte - 1346 ;containing BC shifted so that the least significant - 1347 ;bit is in the low order accumulator position. HL is - 1348 ;the address of the byte for possible replacement in - 1349 ;memory upon return, and D contains the number of shifts - 1350 ;required to place the returned value back into position - 0485 79 1351 ld a,c -q 0486 1352 and 111b - 0486 3C 1353 inc a - 0487 5F 1354 ld e,a - 0488 57 1355 ld d,a - 1356 ;d and e both contain the number of bit positions to shift - 0489 79 1357 ld a,c - 048A 0F 1358 rrca - 048B 0F 1359 rrca - 048C 0F 1360 rrca -q 048D 1361 and 11111b - 048D 4F 1362 ld c,a ;C shr 3 to C - 048E 78 1363 ld a,b - 048F 87 1364 add a,a - 0490 87 1365 add a,a - 0491 87 1366 add a,a - 0492 87 1367 add a,a - 0493 87 1368 add a,a ;B shl 5 - 0494 B1 1369 or c - 0495 4F 1370 ld c,a ;bbbccccc to C - 0496 78 1371 ld a,b - 0497 0F 1372 rrca - 0498 0F 1373 rrca - 0499 0F 1374 rrca -q 049A 1375 and 11111b - 049A 47 1376 ld b,a ;BC shr 3 to BC - 049B 2ArC6s0A 1377 ld hl,(alloca) ;base address of allocation vector - 049E 09 1378 add hl,bc - 049F 7E 1379 ld a,(hl) ;byte to A, hl = .alloc(BC shr 3) - 1380 ;now move the bit to the low order position of A - 04A0 07 1381 rotl: rlca - 04A1 1D 1382 dec e - 04A2 C2rA0s04 1383 jp nz,rotl - 04A5 C9 1384 ret - 1385 - 1386 - 04A6 1387 set$alloc$bit: ;BC is the bit position of ALLOC to set or reset. The - 1388 ;value of the bit is in register E. - 04A6 D5 1389 push de - 04A7 CDr85s04 1390 call getallocbit ;shifted val A, count in D -q 04AA 1391 and 11111110b ;mask low bit to zero (may be set) - 04AA C1 1392 pop bc - 04AB B1 1393 or c ;low bit of C is masked into A - 1394 ; jp rotr ;to rotate back into proper position - 1395 ; ret - 04AC 1396 rotr: - 1397 ;byte value from ALLOC is in register A, with shift count - 1398 ;in register C (to place bit back into position), and - 1399 ;target ALLOC position in registers HL, rotate and replace - 04AC 0F 1400 rrca - 04AD 15 1401 dec d - 04AE C2rACs04 1402 jp nz,rotr ;back into position - 04B1 77 1403 ld (hl),a ;back to ALLOC - 04B2 C9 1404 ret - 1405 - 04B3 1406 scandm: ;scan the disk map addressed by dptr for non-zero - 1407 ;entries, the allocation vector entry corresponding - 1408 ;to a non-zero entry is set to the value of C (0,1) - 04B3 CDrCBs03 1409 call getdptra ;HL = buffa + dptr - 1410 ;HL addresses the beginning of the directory entry -ua 04B6 1411 ld de,dskmap - 04B6 19 1412 add hl,de ;hl now addresses the disk map - 04B7 C5 1413 push bc ;save the 0/1 bit to set -ua 04B8 1414 ld c,fcblen-dskmap+1;size of single byte disk map + 1 - 04B8 1415 scandm0: ;loop once for each disk map entry - 04B8 D1 1416 pop de ;recall bit parity - 04B9 0D 1417 dec c - 04BA C8 1418 ret z ;all done scanning? - 1419 ;no, get next entry for scan - 04BB D5 1420 push de ;replace bit parity - 04BC 3ArC6s0A 1421 ld a,(single) - 04BF B7 1422 or a - 04C0 CArC9s04 1423 jp z,scandm1 - 1424 ;single byte scan operation - 04C3 C5 1425 push bc ;save counter - 04C4 E5 1426 push hl ;save map address - 04C5 4E 1427 ld c,(hl) -a 04C6 1428 ld b,0 ;BC=block# - 04C6 C3rCFs04 1429 jp scandm2 - 1430 - 04C9 1431 scandm1: ;double byte scan operation - 04C9 0D 1432 dec c ;count for double byte - 04CA C5 1433 push bc ;save counter - 04CB 4E 1434 ld c,(hl) - 04CC 23 1435 inc hl - 04CD 46 1436 ld b,(hl) ;BC=block# - 04CE E5 1437 push hl ;save map address - 04CF 1438 scandm2: ;arrive here with BC=block#, E=0/1 - 04CF 79 1439 ld a,c - 04D0 B0 1440 or b ;skip if = 0000 - 04D1 CArDEs04 1441 jp z,scanm3 - 04D4 2ArC6s0A 1442 ld hl,(maxall) ;check invalid index - 04D7 7D 1443 ld a,l - 04D8 91 1444 sub c - 04D9 7C 1445 ld a,h - 04DA 98 1446 sbc a,b ;maxall - block# - 04DB D4rA6s04 1447 call nc,set$alloc$bit - 1448 ;bit set to 0/1 - 04DE E1 1449 scanm3: pop hl - 04DF 23 1450 inc hl ;to next bit position - 04E0 C1 1451 pop bc ;recall counter - 04E1 C3rB8s04 1452 jp scandm0 ;for another item - 1453 - 04E4 1454 initialize: ;initialize the current disk - 1455 ;lret = false ;set to true if $ file exists - 1456 ;compute the length of the allocation vector - 2 - 04E4 2ArC6s0A 1457 ld hl,(maxall) -a 04E7 1458 ld c,3 ;perform maxall/8 - 1459 ;number of bytes in alloc vector is (maxall/8)+1 - 04E7 CDr6As03 1460 call hlrotr - 04EA 23 1461 inc hl ;HL = maxall/8+1 - 04EB 44 1462 ld b,h - 04EC 4D 1463 ld c,l ;count down BC til zero - 04ED 2ArC6s0A 1464 ld hl,(alloca) ;base of allocation vector - 1465 ;fill the allocation vector with zeros - 04F0 1466 initial0: -a 04F0 1467 ld (hl),0 - 04F0 23 1468 inc hl ;alloc(i)=0 - 04F1 0B 1469 dec bc ;count length down - 04F2 78 1470 ld a,b - 04F3 B1 1471 or c - 04F4 C2rF0s04 1472 jp nz,initial0 - 1473 ;set the reserved space for the directory - 04F7 2ArC6s0A 1474 ld hl,(dirblk) - 04FA EB 1475 ex de,hl - 04FB 2ArC6s0A 1476 ld hl,(alloca) ;HL=.alloc() - 04FE 73 1477 ld (hl),e - 04FF 23 1478 inc hl - 0500 72 1479 ld (hl),d ;sets reserved directory blks - 1480 ;allocation vector initialized, home disk - 0501 CDr40s02 1481 call home - 1482 ;cdrmax = 3 (scans at least one directory record) - 0504 2ArC6s0A 1483 ld hl,(cdrmaxa) -a 0507 1484 ld (hl),3 - 0507 23 1485 inc hl -a 0508 1486 ld (hl),0 - 1487 ;cdrmax = 0000 - 0508 CDr55s04 1488 call set$end$dir ;dcnt = enddir - 1489 ;read directory entries and check for allocated storage - 050B 1490 initial2: -ua 050B 1491 ld c,true - 050B CDr59s04 1492 call read$dir - 050E CDr4Fs04 1493 call end$of$dir - 0511 C8 1494 ret z ;return if end of directory - 1495 ;not end of directory, valid entry? - 0512 CDrCBs03 1496 call getdptra ;HL = buffa + dptr -ua 0515 1497 ld a,empty - 0515 BE 1498 cp (hl) - 0516 CAr0Bs05 1499 jp z,initial2 ;go get another item - 1500 ;not empty, user code the same? - 0519 3ArFCs01 1501 ld a,(usrcode) - 051C BE 1502 cp (hl) - 051D C2r29s05 1503 jp nz,pdollar - 1504 ;same user code, check for '$' submit - 0520 23 1505 inc hl - 0521 7E 1506 ld a,(hl) ;first character -q 0522 1507 sub '$' ;dollar file? - 0522 C2r29s05 1508 jp nz,pdollar - 1509 ;dollar file found, mark in lret - 0525 3D 1510 dec a -u 0526 32 00 00 1511 ld (lret),a ;lret = 255 - 0529 1512 pdollar: ;now scan the disk map for allocated blocks -a 0529 1513 ld c,1 ;set to allocated - 0529 CDrB3s04 1514 call scandm - 052C CDrF2s03 1515 call setcdr ;set cdrmax to dcnt - 052F C3r0Bs05 1516 jp initial2 ;for another entry - 1517 - 0532 1518 copy$dirloc: ;copy directory location to lret following - 1519 ;delete, rename, ... ops - 0532 3ArC6s0A 1520 ld a,(dirloc) - 0535 C3rF5s01 1521 jp sta$ret - 1522 ; ret - 1523 - 0538 1524 compext: ;compare extent# in A with that in C, return nonzero - 1525 ;if they do not match - 0538 C5 1526 push bc ;save C's original value - 0539 F5 1527 push af - 053A 3ArC6s0A 1528 ld a,(extmsk) - 053D 2F 1529 cpl - 053E 47 1530 ld b,a - 1531 ;B has negated form of extent mask - 053F 79 1532 ld a,c - 0540 A0 1533 and b - 0541 4F 1534 ld c,a ;low bits removed from C - 0542 F1 1535 pop af - 0543 A0 1536 and b ;low bits removed from A - 0544 91 1537 sub c -ua 0545 1538 and maxext ;set flags - 0545 C1 1539 pop bc ;restore original values - 0546 C9 1540 ret - 1541 - 0547 1542 search: ;search for directory element of length C at info -ao 0547 1543 ld a,0ffh - 0547 32rC6s0A 1544 ld (dirloc),a ;changed if actually found -a 054A 1545 ld hl,searchl - 054A 71 1546 ld (hl),c ;searchl = C - 054B 2ArFCs01 1547 ld hl,(info) - 054E 22rC6s0A 1548 ld (searcha),hl ;searcha = info - 0551 CDr55s04 1549 call set$end$dir ;dcnt = enddir - 0554 CDr40s02 1550 call home ;to start at the beginning - 1551 ;(drop through to searchn) - 1552 - 0557 1553 searchn: ;search for the next directory element, assuming - 1554 ;a previous call on search which sets searcha and - 1555 ;searchl -ua 0557 1556 ld c,false - 0557 CDr59s04 1557 call read$dir ;read next dir element - 055A CDr4Fs04 1558 call end$of$dir - 055D CArABs05 1559 jp z,search$fin ;skip to end if so - 1560 ;not end of directory, scan for match - 0560 2ArC6s0A 1561 ld hl,(searcha) - 0563 EB 1562 ex de,hl ;DE=beginning of user fcb - 0564 1A 1563 ld a,(de) ;first character -ua 0565 1564 cp empty ;keep scanning if empty - 0565 CAr70s05 1565 jp z,searchnext - 1566 ;not empty, may be end of logical directory - 0568 D5 1567 push de ;save search address - 0569 CDrE5s03 1568 call compcdr ;past logical end? - 056C D1 1569 pop de ;recall address - 056D D2rABs05 1570 jp nc,search$fin ;artificial stop - 0570 1571 searchnext: - 0570 CDrCBs03 1572 call getdptra ;HL = buffa+dptr - 0573 3ArC6s0A 1573 ld a,(searchl) - 0576 4F 1574 ld c,a ;length of search to c -a 0577 1575 ld b,0 ;b counts up, c counts down - 0577 1576 searchloop: - 0577 79 1577 ld a,c - 0578 B7 1578 or a - 0579 CAr9Fs05 1579 jp z,endsearch - 057C 1A 1580 ld a,(de) -q 057D 1581 cp '?' - 057D CAr98s05 1582 jp z,searchok ;? matches all - 1583 ;scan next character if not ubytes - 0580 78 1584 ld a,b -ua 0581 1585 cp ubytes - 0581 CAr98s05 1586 jp z,searchok - 1587 ;not the ubytes field, extent field? -ua 0584 1588 cp extnum ;may be extent field - 0584 1A 1589 ld a,(de) ;fcb character - 0585 CAr8Fs05 1590 jp z,searchext ;skip to search extent - 0588 96 1591 sub (hl) -q 0589 1592 and 7fh ;mask-out flags/extent modulus - 0589 C2r57s05 1593 jp nz,searchn ;skip if not matched - 058C C3r98s05 1594 jp searchok ;matched character - 1595 - 058F 1596 searchext: ;A has fcb character - 1597 ;attempt an extent # match - 058F C5 1598 push bc ;save counters - 0590 4E 1599 ld c,(hl) ;directory character to c - 0591 CDr38s05 1600 call compext ;compare user/dir char - 0594 C1 1601 pop bc ;recall counters - 0595 C2r57s05 1602 jp nz,searchn ;skip if no match - 0598 1603 searchok: ;current character matches - 0598 13 1604 inc de - 0599 23 1605 inc hl - 059A 04 1606 inc b - 059B 0D 1607 dec c - 059C C3r77s05 1608 jp searchloop - 1609 - 059F 1610 endsearch: ;entire name matches, return dir position - 059F 3ArC6s0A 1611 ld a,(dcnt) -ua 05A2 1612 and dskmsk -u 05A2 32 00 00 1613 ld (lret),a - 1614 ;lret = low(dcnt) and 11b -a 05A5 1615 ld hl,dirloc - 05A5 7E 1616 ld a,(hl) - 05A6 17 1617 rla - 05A7 D0 1618 ret nc ;dirloc=0ffh? - 1619 ;yes, change it to 0 to mark as found - 05A8 AF 1620 xor a - 05A9 77 1621 ld (hl),a ;dirloc=0 - 05AA C9 1622 ret - 1623 - 05AB 1624 search$fin: ;end of directory, or empty name - 05AB CDr55s04 1625 call set$end$dir ;may be artifical end -a 05AE 1626 ld a,255 - 05AE C3rF5s01 1627 jp sta$ret - 1628 - 05B1 1629 delete: ;delete the currently addressed file - 05B1 CDrC4s03 1630 call check$write ;write protected? -ua 05B4 1631 ld c,extnum - 05B4 CDr47s05 1632 call search ;search through file type - 05B7 1633 delete0: - 1634 ;loop while directory matches - 05B7 CDr4Fs04 1635 call end$of$dir - 05BA C8 1636 ret z ;stop if end - 1637 ;set each non zero disk map entry to 0 - 1638 ;in the allocation vector - 1639 ;may be r/o file - 05BB CDrBAs03 1640 call check$rodir ;ro disk error if found - 05BE CDrCBs03 1641 call getdptra ;HL=.buff(dptr) -ua 05C1 1642 ld (hl),empty -a 05C1 1643 ld c,0 - 05C1 CDrB3s04 1644 call scandm ;alloc elts set to 0 - 05C4 CDr2As04 1645 call wrdir ;write the directory - 05C7 CDr57s05 1646 call searchn ;to next element - 05CA C3rB7s05 1647 jp delete0 ;for another record - 1648 - 05CD 1649 get$block: ;given allocation vector position BC, find the zero bit - 1650 ;closest to this position by searching left and right. - 1651 ;if found, set the bit to one and return the bit position - 1652 ;in hl. if not found (i.e., we pass 0 on the left, or - 1653 ;maxall on the right), return 0000 in hl - 05CD 50 1654 ld d,b - 05CE 59 1655 ld e,c ;copy of starting position to de - 05CF 1656 lefttst: - 05CF 79 1657 ld a,c - 05D0 B0 1658 or b - 05D1 CArE0s05 1659 jp z,righttst ;skip if left=0000 - 1660 ;left not at position zero, bit zero? - 05D4 0B 1661 dec bc - 05D5 D5 1662 push de - 05D6 C5 1663 push bc ;left,right pushed - 05D7 CDr85s04 1664 call getallocbit - 05DA 1F 1665 rra - 05DB D2rFBs05 1666 jp nc,retblock ;return block number if zero - 1667 ;bit is one, so try the right - 05DE C1 1668 pop bc - 05DF D1 1669 pop de ;left, right restored - 05E0 1670 righttst: - 05E0 2ArC6s0A 1671 ld hl,(maxall) ;value of maximum allocation# - 05E3 7B 1672 ld a,e - 05E4 95 1673 sub l - 05E5 7A 1674 ld a,d - 05E6 9C 1675 sbc a,h ;right=maxall? - 05E7 D2r03s06 1676 jp nc,retblock0 ;return block 0000 if so - 05EA 13 1677 inc de - 05EB C5 1678 push bc - 05EC D5 1679 push de ;left, right pushed - 05ED 42 1680 ld b,d - 05EE 4B 1681 ld c,e ;ready right for call - 05EF CDr85s04 1682 call getallocbit - 05F2 1F 1683 rra - 05F3 D2rFBs05 1684 jp nc,retblock ;return block number if zero - 05F6 D1 1685 pop de - 05F7 C1 1686 pop bc ;restore left and right pointers - 05F8 C3rCFs05 1687 jp lefttst ;for another attempt - 05FB 1688 retblock: - 05FB 17 1689 rla - 05FC 3C 1690 inc a ;bit back into position and set to 1 - 1691 ;d contains the number of shifts required to reposition - 05FD CDrACs04 1692 call rotr ;move bit back to position and store - 0600 E1 1693 pop hl - 0601 D1 1694 pop de ;HL returned value, DE discarded - 0602 C9 1695 ret - 1696 - 0603 1697 retblock0: ;cannot find an available bit, return 0000 - 0603 79 1698 ld a,c - 0604 B0 1699 or b - 0605 C2rCFs05 1700 jp nz,lefttst ;also at beginning -ao 0608 1701 ld hl,0000h - 0608 C9 1702 ret - 1703 - 0609 1704 copy$fcb: ;copy the entire file control block -a 0609 1705 ld c,0 -ua 0609 1706 ld e,fcblen ;start at 0, to fcblen-1 - 1707 ; jp copy$dir - 1708 - 0609 1709 copy$dir: ;copy fcb information starting at C for E bytes - 1710 ;into the currently addressed directory entry - 0609 D5 1711 push de ;save length for later -a 060A 1712 ld b,0 ;double index to BC - 060A 2ArFCs01 1713 ld hl,(info) ;HL = source for data - 060D 09 1714 add hl,bc - 060E EB 1715 ex de,hl ;DE=.fcb(C), source for copy - 060F CDrCBs03 1716 call getdptra ;HL=.buff(dptr), destination - 0612 C1 1717 pop bc ;DE=source, HL=dest, C=length - 0613 CDr01s02 1718 call move ;data moved - 0616 1719 seek$copy: ;enter from close to seek and copy current element - 0616 CDr5Fs02 1720 call seek$dir ;to the directory element - 0619 C3r2As04 1721 jp wrdir ;write the directory element - 1722 ; ret - 061C 1723 rename: ;rename the file described by the first half of - 1724 ;the currently addressed file control block. the - 1725 ;new name is contained in the last half of the - 1726 ;currently addressed file conrol block. the file - 1727 ;name and type are changed, but the reel number - 1728 ;is ignored. the user number is identical - 061C CDrC4s03 1729 call check$write ;may be write protected - 1730 ;search up to the extent field -ua 061F 1731 ld c,extnum - 061F CDr47s05 1732 call search - 1733 ;copy position 0 - 0622 2ArFCs01 1734 ld hl,(info) - 0625 7E 1735 ld a,(hl) ;HL=.fcb(0), A=fcb(0) -ua 0626 1736 ld de,dskmap - 0626 19 1737 add hl,de ;HL=.fcb(dskmap) - 0627 77 1738 ld (hl),a ;fcb(dskmap)=fcb(0) - 1739 ;assume the same disk drive for new named file - 0628 1740 rename0: - 0628 CDr4Fs04 1741 call end$of$dir - 062B C8 1742 ret z ;stop at end of dir - 1743 ;not end of directory, rename next element - 062C CDrBAs03 1744 call check$rodir ;may be read-only file -ua 062F 1745 ld c,dskmap -ua 062F 1746 ld e,extnum - 062F CDr09s06 1747 call copy$dir - 1748 ;element renamed, move to next - 0632 CDr57s05 1749 call searchn - 0635 C3r28s06 1750 jp rename0 - 1751 - 0638 1752 indicators: ;set file indicators for current fcb -ua 0638 1753 ld c,extnum - 0638 CDr47s05 1754 call search ;through file type - 063B CDr4Fs04 1755 indic0: call end$of$dir - 063E C8 1756 ret z ;stop at end of dir - 1757 ;not end of directory, continue to change -a 063F 1758 ld c,0 -ua 063F 1759 ld e,extnum ;copy name - 063F CDr09s06 1760 call copy$dir - 0642 CDr57s05 1761 call searchn - 0645 C3r3Bs06 1762 jp indic0 - 1763 - 0648 1764 open: ;search for the directory entry, copy to fcb -ua 0648 1765 ld c,namlen - 0648 CDr47s05 1766 call search - 064B CDr4Fs04 1767 call end$of$dir - 064E C8 1768 ret z ;return with lret=255 if end - 1769 ;not end of directory, copy fcb information - 064F 1770 open$copy: ;(referenced below to copy fcb info) - 064F CDr31s03 1771 call getexta - 0652 7E 1772 ld a,(hl) - 0653 F5 1773 push af - 0654 E5 1774 push hl ;save extent# - 0655 CDrCBs03 1775 call getdptra - 0658 EB 1776 ex de,hl ;DE = .buff(dptr) - 0659 2ArFCs01 1777 ld hl,(info) ;HL=.fcb(0) -ua 065C 1778 ld c,nxtrec ;length of move operation - 065C D5 1779 push de ;save .buff(dptr) - 065D CDr01s02 1780 call move ;from .buff(dptr) to .fcb(0) - 1781 ;note that entire fcb is copied, including indicators - 0660 CDrE0s03 1782 call setfwf ;sets file write flag - 0663 D1 1783 pop de -ua 0664 1784 ld hl,extnum - 0664 19 1785 add hl,de ;HL=.buff(dptr+extnum) - 0665 4E 1786 ld c,(hl) ;C = directory extent number -ua 0666 1787 ld hl,reccnt - 0666 19 1788 add hl,de ;HL=.buff(dptr+reccnt) - 0667 46 1789 ld b,(hl) ;B holds directory record count - 0668 E1 1790 pop hl - 0669 F1 1791 pop af - 066A 77 1792 ld (hl),a ;restore extent number - 1793 ;HL = .user extent#, B = dir rec cnt, C = dir extent# - 1794 ;if user ext < dir ext then user := 128 records - 1795 ;if user ext = dir ext then user := dir records - 1796 ;if user ext > dir ext then user := 0 records - 066B 79 1797 ld a,c - 066C BE 1798 cp (hl) - 066D 78 1799 ld a,b ;ready dir reccnt - 066E CAr74s06 1800 jp z,open$rcnt ;if same, user gets dir reccnt -a 0671 1801 ld a,0 - 0671 DAr74s06 1802 jp c,open$rcnt ;user is larger -a 0674 1803 ld a,128 ;directory is larger - 0674 1804 open$rcnt: ;A has record count to fill - 0674 2ArFCs01 1805 ld hl,(info) -ua 0677 1806 ld de,reccnt - 0677 19 1807 add hl,de - 0678 77 1808 ld (hl),a - 0679 C9 1809 ret - 1810 - 067A 1811 mergezero: ;HL = .fcb1(i), DE = .fcb2(i), - 1812 ;if fcb1(i) = 0 then fcb1(i) := fcb2(i) - 067A 7E 1813 ld a,(hl) - 067B 23 1814 inc hl - 067C B6 1815 or (hl) - 067D 2B 1816 dec hl - 067E C0 1817 ret nz ;return if = 0000 - 067F 1A 1818 ld a,(de) - 0680 77 1819 ld (hl),a - 0681 13 1820 inc de - 0682 23 1821 inc hl ;low byte copied - 0683 1A 1822 ld a,(de) - 0684 77 1823 ld (hl),a - 0685 1B 1824 dec de - 0686 2B 1825 dec hl ;back to input form - 0687 C9 1826 ret - 1827 - 0688 1828 close: ;locate the directory element and re-write it - 0688 AF 1829 xor a -u 0689 32 00 00 1830 ld (lret),a - 068C 32rC6s0A 1831 ld (dcnt),a - 068F 32rC7s0A 1832 ld (dcnt+1),a - 0692 CDr99s03 1833 call nowrite - 0695 C0 1834 ret nz ;skip close if r/o disk - 1835 ;check file write flag - 0 indicates written - 0696 CDrD6s03 1836 call getmodnum ;fcb(modnum) in A -ua 0699 1837 and fwfmsk - 0699 C0 1838 ret nz ;return if bit remains set -ua 069A 1839 ld c,namlen - 069A CDr47s05 1840 call search ;locate file - 069D CDr4Fs04 1841 call end$of$dir - 06A0 C8 1842 ret z ;return if not found - 1843 ;merge the disk map at info with that at buff(dptr) -ua 06A1 1844 ld bc,dskmap - 06A1 CDrCBs03 1845 call getdptra - 06A4 09 1846 add hl,bc - 06A5 EB 1847 ex de,hl ;DE is .buff(dptr+16) - 06A6 2ArFCs01 1848 ld hl,(info) - 06A9 09 1849 add hl,bc ;DE=.buff(dptr+16), HL=.fcb(16) -ua 06AA 1850 ld c,fcblen-dskmap;length of single byte dm - 06AA 3ArC6s0A 1851 merge0: ld a,(single) - 06AD B7 1852 or a - 06AE CArC5s06 1853 jp z,merged ;skip to double - 1854 ;this is a single byte map - 1855 ;if fcb(i) = 0 then fcb(i) = buff(i) - 1856 ;if buff(i) = 0 then buff(i) = fcb(i) - 1857 ;if fcb(i) <> buff(i) then error - 06B1 7E 1858 ld a,(hl) - 06B2 B7 1859 or a - 06B3 1A 1860 ld a,(de) - 06B4 C2rB8s06 1861 jp nz,fcbnzero - 1862 ;fcb(i) = 0 - 06B7 77 1863 ld (hl),a ;fcb(i) = buff(i) - 06B8 1864 fcbnzero: - 06B8 B7 1865 or a - 06B9 C2rBEs06 1866 jp nz,buffnzero - 1867 ;buff(i) = 0 - 06BC 7E 1868 ld a,(hl) - 06BD 12 1869 ld (de),a ;buff(i)=fcb(i) - 06BE 1870 buffnzero: - 06BE BE 1871 cp (hl) - 06BF C2rF4s06 1872 jp nz,mergerr ;fcb(i) = buff(i)? - 06C2 C3rDAs06 1873 jp dmset ;if merge ok - 1874 - 06C5 1875 merged: ;this is a double byte merge operation - 06C5 CDr7As06 1876 call mergezero ;buff = fcb if buff 0000 - 06C8 EB 1877 ex de,hl - 06C9 CDr7As06 1878 call mergezero - 06CC EB 1879 ex de,hl ;fcb = buff if fcb 0000 - 1880 ;they should be identical at this point - 06CD 1A 1881 ld a,(de) - 06CE BE 1882 cp (hl) - 06CF C2rF4s06 1883 jp nz,mergerr ;low same? - 06D2 13 1884 inc de - 06D3 23 1885 inc hl ;to high byte - 06D4 1A 1886 ld a,(de) - 06D5 BE 1887 cp (hl) - 06D6 C2rF4s06 1888 jp nz,mergerr ;high same? - 1889 ;merge operation ok for this pair - 06D9 0D 1890 dec c ;extra count for double byte - 06DA 13 1891 dmset: inc de - 06DB 23 1892 inc hl ;to next byte position - 06DC 0D 1893 dec c - 06DD C2rAAs06 1894 jp nz,merge0 ;for more - 1895 ;end of disk map merge, check record count - 1896 ;DE = .buff(dptr)+32, HL = .fcb(32) -ua 06E0 1897 ld bc,-(fcblen-extnum) - 06E0 09 1898 add hl,bc - 06E1 EB 1899 ex de,hl - 06E2 09 1900 add hl,bc - 1901 ;DE = .fcb(extnum), HL = .buff(dptr+extnum) - 06E3 1A 1902 ld a,(de) ;current user extent number - 1903 ;if fcb(ext) >= buff(fcb) then - 1904 ;buff(ext) := fcb(ext), buff(rec) := fcb(rec) - 06E4 BE 1905 cp (hl) - 06E5 DArEEs06 1906 jp c,endmerge - 1907 ;fcb extent number >= dir extent number - 06E8 77 1908 ld (hl),a ;buff(ext) = fcb(ext) - 1909 ;update directory record count field -ua 06E9 1910 ld bc,reccnt-extnum - 06E9 09 1911 add hl,bc - 06EA EB 1912 ex de,hl - 06EB 09 1913 add hl,bc - 1914 ;DE=.buff(reccnt), HL=.fcb(reccnt) - 06EC 7E 1915 ld a,(hl) - 06ED 12 1916 ld (de),a ;buff(reccnt)=fcb(reccnt) - 06EE 1917 endmerge: -ua 06EE 1918 ld a,true - 06EE 32rC6s0A 1919 ld (fcb$copied),a ;mark as copied - 06F1 C3r16s06 1920 jp seek$copy ;ok to "wrdir" here - 1.4 compat - 1921 ; ret - 1922 - 06F4 1923 mergerr: ;elements did not merge correctly -ua 06F4 1924 ld hl,lret - 06F4 35 1925 dec (hl) ;=255 non zero flag set - 06F5 C9 1926 ret - 1927 - 06F6 1928 make: ;create a new file by creating a directory entry - 1929 ;then opening the file - 06F6 CDrC4s03 1930 call check$write ;may be write protected - 06F9 2ArFCs01 1931 ld hl,(info) - 06FC E5 1932 push hl ;save fcb address, look for e5 -a 06FD 1933 ld hl,efcb - 06FD 22rFCs01 1934 ld (info),hl ;info = .empty -a 0700 1935 ld c,1 - 0700 CDr47s05 1936 call search ;length 1 match on empty entry - 0703 CDr4Fs04 1937 call end$of$dir ;zero flag set if no space - 0706 E1 1938 pop hl ;recall info address - 0707 22rFCs01 1939 ld (info),hl ;in case we return here - 070A C8 1940 ret z ;return with error condition 255 if not found - 070B EB 1941 ex de,hl ;DE = info address - 1942 ;clear the remainder of the fcb -ua 070C 1943 ld hl,namlen - 070C 19 1944 add hl,de ;HL=.fcb(namlen) -ua 070D 1945 ld c,fcblen-namlen ;number of bytes to fill - 070D AF 1946 xor a ;clear accumulator to 00 for fill - 070E 77 1947 make0: ld (hl),a - 070F 23 1948 inc hl - 0710 0D 1949 dec c - 0711 C2r0Es07 1950 jp nz,make0 -ua 0714 1951 ld hl,ubytes - 0714 19 1952 add hl,de ;HL = .fcb(ubytes) - 0715 77 1953 ld (hl),a ;fcb(ubytes) = 0 - 0716 CDrF2s03 1954 call setcdr ;may have extended the directory - 1955 ;now copy entry to the directory - 0719 CDr09s06 1956 call copy$fcb - 1957 ;and set the file write flag to "1" - 071C C3rE0s03 1958 jp setfwf - 1959 ; ret - 1960 - 071F 1961 open$reel: ;close the current extent, and open the next one - 1962 ;if possible. RMF is true if in read mode - 071F AF 1963 xor a - 0720 32rC6s0A 1964 ld (fcb$copied),a ;set true if actually copied - 0723 CDr88s06 1965 call close ;close current extent - 1966 ;lret remains at enddir if we cannot open the next ext - 0726 CDr4Fs04 1967 call end$of$dir - 0729 C8 1968 ret z ;return if end - 1969 ;increment extent number - 072A 2ArFCs01 1970 ld hl,(info) -ua 072D 1971 ld bc,extnum - 072D 09 1972 add hl,bc ;HL=.fcb(extnum) - 072E 7E 1973 ld a,(hl) - 072F 3C 1974 inc a -ua 0730 1975 and maxext - 0730 77 1976 ld (hl),a ;fcb(extnum)=++1 - 0731 CAr40s07 1977 jp z,open$mod ;move to next module if zero - 1978 ;may be in the same extent group - 0734 47 1979 ld b,a - 0735 3ArC6s0A 1980 ld a,(extmsk) - 0738 A0 1981 and b - 1982 ;if result is zero, then not in the same group -a 0739 1983 ld hl,fcb$copied ;true if the fcb was copied to directory - 0739 A6 1984 and (hl) ;produces a 00 in accumulator if not written - 073A CAr46s07 1985 jp z,open$reel0 ;go to next physical extent - 1986 ;result is non zero, so we must be in same logical ext - 073D C3r62s07 1987 jp open$reel1 ;to copy fcb information - 0740 1988 open$mod: ;extent number overflow, go to next module -ua 0740 1989 ld bc,modnum-extnum - 0740 09 1990 add hl,bc ;HL=.fcb(modnum) - 0741 34 1991 inc (hl) ;fcb(modnum)=++1 - 1992 ;module number incremented, check for overflow - 0742 7E 1993 ld a,(hl) -ua 0743 1994 and maxmod ;mask high order bits - 0743 CAr6Cs07 1995 jp z,open$r$err ;cannot overflow to zero - 1996 ;otherwise, ok to continue with new module - 0746 1997 open$reel0: -ua 0746 1998 ld c,namlen - 0746 CDr47s05 1999 call search ;next extent found? - 0749 CDr4Fs04 2000 call end$of$dir - 074C C2r62s07 2001 jp nz,open$reel1 - 2002 ;end of file encountered - 074F 3ArC6s0A 2003 ld a,(rmf) - 0752 3C 2004 inc a ;0ffh becomes 00 if read - 0753 CAr6Cs07 2005 jp z,open$r$err ;sets lret = 1 - 2006 ;try to extend the current file - 0756 CDrF6s06 2007 call make - 2008 ;cannot be end of directory - 0759 CDr4Fs04 2009 call end$of$dir - 075C CAr6Cs07 2010 jp z,open$r$err ;with lret = 1 - 075F C3r65s07 2011 jp open$reel2 - 2012 - 0762 2013 open$reel1: ;not end of file, open - 0762 CDr4Fs06 2014 call open$copy - 0765 2015 open$reel2: - 0765 CDr3Ds03 2016 call getfcb ;set parameters - 0768 AF 2017 xor a - 0769 C3rF5s01 2018 jp sta$ret ;lret = 0 - 2019 ; ret ;with lret = 0 - 2020 - 076C 2021 open$r$err: ;cannot move to next extent of this file - 076C CDrF9s01 2022 call setlret1 ;lret = 1 - 076F C3rE0s03 2023 jp setfwf ;ensure that it will not be closed - 2024 ; ret - 2025 - 0772 2026 seqdiskread: ;sequential disk read operation -a 0772 2027 ld a,1 - 0772 32rC6s0A 2028 ld (seqio),a - 2029 ;drop through to diskread - 2030 - 0775 2031 diskread: ;(may enter from seqdiskread) -ua 0775 2032 ld a,true - 0775 32rC6s0A 2033 ld (rmf),a ;read mode flag = true (open$reel) - 2034 ;read the next record from the current fcb - 0778 CDr3Ds03 2035 call getfcb ;sets parameters for the read - 077B 3ArC6s0A 2036 ld a,(vrecord) -a 077E 2037 ld hl,rcount - 077E BE 2038 cp (hl) ;vrecord-rcount - 2039 ;skip if rcount > vrecord - 077F DAr93s07 2040 jp c,recordok - 2041 ;not enough records in the extent - 2042 ;record count must be 128 to continue -a 0782 2043 cp 128 ;vrecord = 128? - 0782 C2rA8s07 2044 jp nz,diskeof ;skip if vrecord<>128 - 0785 CDr1Fs07 2045 call open$reel ;go to next extent if so - 0788 AF 2046 xor a - 0789 32rC6s0A 2047 ld (vrecord),a ;vrecord=00 - 2048 ;now check for open ok -u 078C 3A 00 00 2049 ld a,(lret) - 078F B7 2050 or a - 0790 C2rA8s07 2051 jp nz,diskeof ;stop at eof - 0793 2052 recordok: ;arrive with fcb addressing a record to read - 0793 CDr04s03 2053 call index - 2054 ;error 2 if reading unwritten data - 2055 ;(returns 1 to be compatible with 1.4) - 0796 CDr0Fs03 2056 call allocated ;arecord=0000? - 0799 CArA8s07 2057 jp z,diskeof - 2058 ;record has been allocated, read it - 079C CDr15s03 2059 call atran ;arecord now a disk address - 079F CDr6Bs02 2060 call seek ;to proper track,sector - 07A2 CDr51s02 2061 call rdbuff ;to dma address - 07A5 C3r54s03 2062 jp setfcb ;replace parameter - 2063 ; ret - 2064 - 07A8 2065 diskeof: - 07A8 C3rF9s01 2066 jp setlret1 ;lret = 1 - 2067 ; ret - 2068 - 07AB 2069 seqdiskwrite: ;sequential disk write -a 07AB 2070 ld a,1 - 07AB 32rC6s0A 2071 ld (seqio),a - 2072 ;drop through to diskwrite - 2073 - 07AE 2074 diskwrite: ;(may enter here from seqdiskwrite above) -ua 07AE 2075 ld a,false - 07AE 32rC6s0A 2076 ld (rmf),a ;read mode flag - 2077 ;write record to currently selected file - 07B1 CDrC4s03 2078 call check$write ;in case write protected - 07B4 2ArFCs01 2079 ld hl,(info) ;HL = .fcb(0) - 07B7 CDrBDs03 2080 call check$rofile ;may be a read-only file - 07BA CDr3Ds03 2081 call getfcb ;to set local parameters - 07BD 3ArC6s0A 2082 ld a,(vrecord) -ua 07C0 2083 cp lstrec+1 ;vrecord-128 - 2084 ;skip if vrecord > lstrec - 2085 ;vrecord = 128, cannot open next extent - 07C0 D2rF9s01 2086 jp nc,setlret1 ;lret=1 - 07C3 2087 diskwr0: ;can write the next record, so continue - 07C3 CDr04s03 2088 call index - 07C6 CDr0Fs03 2089 call allocated -a 07C9 2090 ld c,0 ;marked as normal write operation for wrbuff - 07C9 C2r07s08 2091 jp nz,diskwr1 - 2092 ;not allocated - 2093 ;the argument to getblock is the starting - 2094 ;position for the disk search, and should be - 2095 ;the last allocated block for this file, or - 2096 ;the value 0 if no space has been allocated - 07CC CDrD5s02 2097 call dm$position - 07CF 32rC6s0A 2098 ld (dminx),a ;save for later -ao 07D2 2099 ld bc,0000h ;may use block zero - 07D2 B7 2100 or a - 07D3 CArDDs07 2101 jp z,nopblock ;skip if no previous block - 2102 ;previous block exists at A - 07D6 4F 2103 ld c,a - 07D7 0B 2104 dec bc ;previous block # in BC - 07D8 CDrF0s02 2105 call getdm ;previous block # to HL - 07DB 44 2106 ld b,h - 07DC 4D 2107 ld c,l ;BC=prev block# - 07DD 2108 nopblock: ;BC = 0000, or previous block # - 07DD CDrCDs05 2109 call get$block ;block # to HL - 2110 ;arrive here with block# or zero - 07E0 7D 2111 ld a,l - 07E1 B4 2112 or h - 07E2 C2rE8s07 2113 jp nz,blockok - 2114 ;cannot find a block to allocate -a 07E5 2115 ld a,2 - 07E5 C3rF5s01 2116 jp sta$ret ;lret=2 - 2117 - 07E8 2118 blockok: ;allocated block number is in HL - 07E8 22rC6s0A 2119 ld (arecord),hl - 07EB EB 2120 ex de,hl ;block number to DE - 07EC 2ArFCs01 2121 ld hl,(info) -ua 07EF 2122 ld bc,dskmap - 07EF 09 2123 add hl,bc ;HL=.fcb(dskmap) - 07F0 3ArC6s0A 2124 ld a,(single) - 07F3 B7 2125 or a ;set flags for single byte dm - 07F4 3ArC6s0A 2126 ld a,(dminx) ;recall dm index - 07F7 CAr01s08 2127 jp z,allocwd ;skip if allocating word - 2128 ;allocating a byte value - 07FA CDrD1s03 2129 call addh - 07FD 73 2130 ld (hl),e ;single byte alloc - 07FE C3r07s08 2131 jp diskwru ;to continue - 2132 - 0801 2133 allocwd: ;allocate a word value - 0801 4F 2134 ld c,a -a 0802 2135 ld b,0 ;double(dminx) - 0802 09 2136 add hl,bc - 0803 09 2137 add hl,bc ;HL=.fcb(dminx*2) - 0804 73 2138 ld (hl),e - 0805 23 2139 inc hl - 0806 72 2140 ld (hl),d ;double wd - 0807 2141 diskwru: ;disk write to previously unallocated block -a 0807 2142 ld c,2 ;marked as unallocated write - 0807 2143 diskwr1: ;continue the write operation of no allocation error - 2144 ;C = 0 if normal write, 2 if to prev unalloc block -u 0807 3A 00 00 2145 ld a,(lret) - 080A B7 2146 or a - 080B C0 2147 ret nz ;stop if non zero returned value - 080C C5 2148 push bc ;save write flag - 080D CDr15s03 2149 call atran ;arecord set - 0810 3ArC6s0A 2150 ld a,(seqio) - 0813 3D 2151 dec a - 0814 3D 2152 dec a - 0815 C2r50s08 2153 jp nz,diskwr11 - 0818 C1 2154 pop bc - 0819 C5 2155 push bc - 081A 79 2156 ld a,c - 081B 3D 2157 dec a - 081C 3D 2158 dec a - 081D C2r50s08 2159 jp nz,diskwr11 ;old allocation - 0820 E5 2160 push hl ;arecord in hl ret from atran - 0821 2ArC6s0A 2161 ld hl,(buffa) - 0824 57 2162 ld d,a ;zero buffa & fill - 0825 77 2163 fill0: ld (hl),a - 0826 23 2164 inc hl - 0827 14 2165 inc d - 0828 F2r25s08 2166 jp p,fill0 - 082B CDr3Fs04 2167 call setdir - 082E 2ArC6s0A 2168 ld hl,(arecord1) -a 0831 2169 ld c,2 - 0831 22rC6s0A 2170 fill1: ld (arecord),hl - 0834 C5 2171 push bc - 0835 CDr6Bs02 2172 call seek - 0838 C1 2173 pop bc - 0839 CDr57s02 2174 call wrbuff ;write fill record - 083C 2ArC6s0A 2175 ld hl,(arecord) ;restore last record -a 083F 2176 ld c,0 ;change allocate flag - 083F 3ArC6s0A 2177 ld a,(blkmsk) - 0842 47 2178 ld b,a - 0843 A5 2179 and l - 0844 B8 2180 cp b - 0845 23 2181 inc hl - 0846 C2r31s08 2182 jp nz,fill1 ;cont until cluster is zeroed - 0849 E1 2183 pop hl - 084A 22rC6s0A 2184 ld (arecord),hl - 084D CDr3Cs04 2185 call setdata - 0850 2186 diskwr11: - 0850 CDr6Bs02 2187 call seek ;to proper file position - 0853 C1 2188 pop bc - 0854 C5 2189 push bc ;restore/save write flag (C=2 if new block) - 0855 CDr57s02 2190 call wrbuff ;written to disk - 0858 C1 2191 pop bc ;C = 2 if a new block was allocated, 0 if not - 2192 ;increment record count if rcount<=vrecord - 0859 3ArC6s0A 2193 ld a,(vrecord) -a 085C 2194 ld hl,rcount - 085C BE 2195 cp (hl) ;vrecord-rcount - 085D DAr62s08 2196 jp c,diskwr2 - 2197 ;rcount <= vrecord - 0860 77 2198 ld (hl),a - 0861 34 2199 inc (hl) ;rcount = vrecord+1 -a 0862 2200 ld c,2 ;mark as record count incremented - 0862 2201 diskwr2: ;A has vrecord, C=2 if new block or new record# - 0862 0D 2202 dec c - 0863 0D 2203 dec c - 0864 C2r6Ds08 2204 jp nz,noupdate - 0867 F5 2205 push af ;save vrecord value - 0868 CDrD6s03 2206 call getmodnum ;HL=.fcb(modnum), A=fcb(modnum) - 2207 ;reset the file write flag to mark as written fcb -uq 086B 2208 and (not fwfmsk) and 0ffh;bit reset - 086B 77 2209 ld (hl),a ;fcb(modnum) = fcb(modnum) and 7fh - 086C F1 2210 pop af ;restore vrecord - 086D 2211 noupdate: ;check for end of extent, if found attempt to open - 2212 ;next extent in preparation for next write -ua 086D 2213 cp lstrec ;vrecord=lstrec? - 086D C2r85s08 2214 jp nz,diskwr3 ;skip if not - 2215 ;may be random access write, if so we are done - 2216 ;change next - 0870 3ArC6s0A 2217 ld a,(seqio) -a 0873 2218 cp 1 - 0873 C2r85s08 2219 jp nz,diskwr3 ;skip next extent open op - 2220 ;update current fcb before going to next extent - 0876 CDr54s03 2221 call setfcb - 0879 CDr1Fs07 2222 call open$reel ;rmf=false - 2223 ;vrecord remains at lstrec causing eof if - 2224 ;no more directory space is available -ua 087C 2225 ld hl,lret - 087C 7E 2226 ld a,(hl) - 087D B7 2227 or a - 087E C2r85s08 2228 jp nz,nospace - 2229 ;space available, set vrecord=255 - 0881 3D 2230 dec a - 0882 32rC6s0A 2231 ld (vrecord),a ;goes to 00 next time - 0885 2232 nospace: -a 0885 2233 ld (hl),0 ;lret = 00 for returned value - 0885 2234 diskwr3: - 0885 C3r54s03 2235 jp setfcb ;replace parameters - 2236 ; ret - 2237 - 0888 2238 rseek: ;random access seek operation, C=0ffh if read mode - 2239 ;fcb is assumed to address an active file control block - 2240 ;(modnum has been set to 1100$0000b if previous bad seek) - 0888 AF 2241 xor a - 0889 32rC6s0A 2242 ld (seqio),a ;marked as random access operation - 088C C5 2243 rseek1: push bc ;save r/w flag - 088D 2ArFCs01 2244 ld hl,(info) - 0890 EB 2245 ex de,hl ;DE will hold base of fcb -ua 0891 2246 ld hl,ranrec - 0891 19 2247 add hl,de ;HL=.fcb(ranrec) - 0892 7E 2248 ld a,(hl) -q 0893 2249 and 7fh - 0893 F5 2250 push af ;record number - 0894 7E 2251 ld a,(hl) - 0895 17 2252 rla ;cy=lsb of extent# - 0896 23 2253 inc hl - 0897 7E 2254 ld a,(hl) - 0898 17 2255 rla -q 0899 2256 and 11111b ;A=ext# - 0899 4F 2257 ld c,a ;C holds extent number, record stacked - 089A 7E 2258 ld a,(hl) - 089B 1F 2259 rra - 089C 1F 2260 rra - 089D 1F 2261 rra - 089E 1F 2262 rra -q 089F 2263 and 1111b ;mod# - 089F 47 2264 ld b,a ;B holds module#, C holds ext# - 08A0 F1 2265 pop af ;recall sought record # - 2266 ;check to insure that high byte of ran rec = 00 - 08A1 23 2267 inc hl - 08A2 6E 2268 ld l,(hl) ;l=high byte (must be 00) - 08A3 2C 2269 inc l - 08A4 2D 2270 dec l -a 08A5 2271 ld l,6 ;zero flag, l=6 - 2272 ;produce error 6, seek past physical eod - 08A5 C2rECs08 2273 jp nz,seekerr - 2274 ;otherwise, high byte = 0, A = sought record -ua 08A8 2275 ld hl,nxtrec - 08A8 19 2276 add hl,de ;HL = .fcb(nxtrec) - 08A9 77 2277 ld (hl),a ;sought rec# stored away - 2278 ;arrive here with B=mod#, C=ext#, DE=.fcb, rec stored - 2279 ;the r/w flag is still stacked. compare fcb values -ua 08AA 2280 ld hl,extnum - 08AA 19 2281 add hl,de - 08AB 79 2282 ld a,c ;A=seek ext# - 08AC 96 2283 sub (hl) - 08AD C2rB6s08 2284 jp nz,ranclose ;tests for = extents - 2285 ;extents match, check mod# -ua 08B0 2286 ld hl,modnum - 08B0 19 2287 add hl,de - 08B1 78 2288 ld a,b ;B=seek mod# - 2289 ;could be overflow at eof, producing module# - 2290 ;of 90H or 10H, so compare all but fwf - 08B2 96 2291 sub (hl) -q 08B3 2292 and 7fh - 08B3 CArE2s08 2293 jp z,seekok ;same? - 08B6 2294 ranclose: - 08B6 C5 2295 push bc - 08B7 D5 2296 push de ;save seek mod#,ext#, .fcb - 08B8 CDr88s06 2297 call close ;current extent closed - 08BB D1 2298 pop de - 08BC C1 2299 pop bc ;recall parameters and fill -a 08BD 2300 ld l,3 ;cannot close error #3 -u 08BD 3A 00 00 2301 ld a,(lret) - 08C0 3C 2302 inc a - 08C1 CArE7s08 2303 jp z,badseek -ua 08C4 2304 ld hl,extnum - 08C4 19 2305 add hl,de - 08C5 71 2306 ld (hl),c ;fcb(extnum)=ext# -ua 08C6 2307 ld hl,modnum - 08C6 19 2308 add hl,de - 08C7 70 2309 ld (hl),b ;fcb(modnum)=mod# - 08C8 CDr48s06 2310 call open ;is the file present? -u 08CB 3A 00 00 2311 ld a,(lret) - 08CE 3C 2312 inc a - 08CF C2rE2s08 2313 jp nz,seekok ;open successful? - 2314 ;cannot open the file, read mode? - 08D2 C1 2315 pop bc ;r/w flag to c (=0ffh if read) - 08D3 C5 2316 push bc ;everyone expects this item stacked -a 08D4 2317 ld l,4 ;seek to unwritten extent #4 - 08D4 0C 2318 inc c ;becomes 00 if read operation - 08D5 CArE7s08 2319 jp z,badseek ;skip to error if read operation - 2320 ;write operation, make new extent - 08D8 CDrF6s06 2321 call make -a 08DB 2322 ld l,5 ;cannot create new extent #5 -u 08DB 3A 00 00 2323 ld a,(lret) - 08DE 3C 2324 inc a - 08DF CArE7s08 2325 jp z,badseek ;no dir space - 2326 ;file make operation successful - 08E2 2327 seekok: - 08E2 C1 2328 pop bc ;discard r/w flag - 08E3 AF 2329 xor a - 08E4 C3rF5s01 2330 jp sta$ret ;with zero set - 08E7 2331 badseek: ;fcb no longer contains a valid fcb, mark - 2332 ;with 1100$000b in modnum field so that it - 2333 ;appears as overflow with file write flag set - 08E7 E5 2334 push hl ;save error flag - 08E8 CDrD6s03 2335 call getmodnum ;HL = .modnum -ao 08EB 2336 ld (hl),11000000b - 08EB E1 2337 pop hl ;and drop through - 08EC 2338 seekerr: - 08EC C1 2339 pop bc ;discard r/w flag - 08ED 7D 2340 ld a,l -u 08EE 32 00 00 2341 ld (lret),a ;lret=#, nonzero - 2342 ;setfwf returns non-zero accumulator for err - 08F1 C3rE0s03 2343 jp setfwf ;flag set, so subsequent close ok - 2344 ; ret - 2345 - 08F4 2346 randiskread: ;random disk read operation -ua 08F4 2347 ld c,true ;marked as read operation - 08F4 CDr88s08 2348 call rseek - 08F7 CCr75s07 2349 call z,diskread ;if seek successful - 08FA C9 2350 ret - 2351 - 08FB 2352 randiskwrite: ;random disk write operation -ua 08FB 2353 ld c,false ;marked as write operation - 08FB CDr88s08 2354 call rseek - 08FE CCrAEs07 2355 call z,diskwrite ;if seek successful - 0901 C9 2356 ret - 2357 - 0902 2358 compute$rr: ;compute random record position for getfilesize/setrandom - 0902 EB 2359 ex de,hl - 0903 19 2360 add hl,de - 2361 ;DE=.buf(dptr) or .fcb(0), HL = .f(nxtrec/reccnt) - 0904 4E 2362 ld c,(hl) -a 0905 2363 ld b,0 ;BC = 0000 0000 ?rrr rrrr -ua 0905 2364 ld hl,extnum - 0905 19 2365 add hl,de - 0906 7E 2366 ld a,(hl) - 0907 0F 2367 rrca -q 0908 2368 and 80h ;A=e000 0000 - 0908 81 2369 add a,c - 0909 4F 2370 ld c,a -a 090A 2371 ld a,0 - 090A 88 2372 adc a,b - 090B 47 2373 ld b,a - 2374 ;BC = 0000 000? errrr rrrr - 090C 7E 2375 ld a,(hl) - 090D 0F 2376 rrca -q 090E 2377 and 0fh - 090E 80 2378 add a,b - 090F 47 2379 ld b,a - 2380 ;BC = 000? eeee errrr rrrr -ua 0910 2381 ld hl,modnum - 0910 19 2382 add hl,de - 0911 7E 2383 ld a,(hl) ;A=XXX? mmmm - 0912 87 2384 add a,a - 0913 87 2385 add a,a - 0914 87 2386 add a,a - 0915 87 2387 add a,a ;cy=? A=mmmm 0000 - 0916 F5 2388 push af - 0917 80 2389 add a,b - 0918 47 2390 ld b,a - 2391 ;cy=?, BC = mmmm eeee errr rrrr - 0919 F5 2392 push af ;possible second carry - 091A E1 2393 pop hl ;cy = lsb of L - 091B 7D 2394 ld a,l ;cy = lsb of A - 091C E1 2395 pop hl ;cy = lsb of L - 091D B5 2396 or l ;cy/cy = lsb of A -a 091E 2397 and 1 ;A = 0000 000? possible carry-out - 091E C9 2398 ret - 2399 - 091F 2400 getfilesize: ;compute logical file size for current fcb -ua 091F 2401 ld c,extnum - 091F CDr47s05 2402 call search - 2403 ;zero the receiving ranrec field - 0922 2ArFCs01 2404 ld hl,(info) -ua 0925 2405 ld de,ranrec - 0925 19 2406 add hl,de - 0926 E5 2407 push hl ;save position - 0927 72 2408 ld (hl),d - 0928 23 2409 inc hl - 0929 72 2410 ld (hl),d - 092A 23 2411 inc hl - 092B 72 2412 ld (hl),d ;=00 00 00 - 092C 2413 getsize: - 092C CDr4Fs04 2414 call end$of$dir - 092F CAr51s09 2415 jp z,setsize - 2416 ;current fcb addressed by dptr - 0932 CDrCBs03 2417 call getdptra -ua 0935 2418 ld de,reccnt ;ready for compute size - 0935 CDr02s09 2419 call compute$rr - 2420 ;A=0000 000? BC = mmmm eeee errr rrrr - 2421 ;compare with memory, larger? - 0938 E1 2422 pop hl - 0939 E5 2423 push hl ;recall, replace .fcb(ranrec) - 093A 5F 2424 ld e,a ;save cy - 093B 79 2425 ld a,c - 093C 96 2426 sub (hl) - 093D 23 2427 inc hl ;ls byte - 093E 78 2428 ld a,b - 093F 9E 2429 sbc a,(hl) - 0940 23 2430 inc hl ;middle byte - 0941 7B 2431 ld a,e - 0942 9E 2432 sbc a,(hl) ;carry if .fcb(ranrec) > directory - 0943 DAr4Bs09 2433 jp c,getnextsize ;for another try - 2434 ;fcb is less or equal, fill from directory - 0946 73 2435 ld (hl),e - 0947 2B 2436 dec hl - 0948 70 2437 ld (hl),b - 0949 2B 2438 dec hl - 094A 71 2439 ld (hl),c - 094B 2440 getnextsize: - 094B CDr57s05 2441 call searchn - 094E C3r2Cs09 2442 jp getsize - 2443 - 0951 2444 setsize: - 0951 E1 2445 pop hl ;discard .fcb(ranrec) - 0952 C9 2446 ret - 2447 - 0953 2448 setrandom: ;set random record from the current file control block - 0953 2ArFCs01 2449 ld hl,(info) -ua 0956 2450 ld de,nxtrec ;ready params for computesize - 0956 CDr02s09 2451 call compute$rr ;DE=info, A=cy, BC=mmmm eeee errr rrrr -ua 0959 2452 ld hl,ranrec - 0959 19 2453 add hl,de ;HL = .fcb(ranrec) - 095A 71 2454 ld (hl),c - 095B 23 2455 inc hl - 095C 70 2456 ld (hl),b - 095D 23 2457 inc hl - 095E 77 2458 ld (hl),a ;to ranrec - 095F C9 2459 ret - 2460 - 0960 2461 select: ;select disk info for subsequent input or output ops - 0960 2ArC6s0A 2462 ld hl,(dlog) - 0963 3ArFCs01 2463 ld a,(curdsk) - 0966 4F 2464 ld c,a - 0967 CDr6As03 2465 call hlrotr - 096A E5 2466 push hl - 096B EB 2467 ex de,hl ;save it for test below, send to seldsk - 096C CDr0Bs02 2468 call selectdisk - 096F E1 2469 pop hl ;recall dlog vector - 0970 CCrFCs01 2470 call z,sel$error ;returns true if select ok - 2471 ;is the disk logged in? - 0973 7D 2472 ld a,l - 0974 1F 2473 rra - 0975 D8 2474 ret c ;return if bit is set - 2475 ;disk not logged in, set bit and initialize - 0976 2ArC6s0A 2476 ld hl,(dlog) - 0979 4D 2477 ld c,l - 097A 44 2478 ld b,h ;call ready - 097B CDr89s03 2479 call set$cdisk - 097E 22rC6s0A 2480 ld (dlog),hl ;dlog=set$cdisk(dlog) - 0981 C3rE4s04 2481 jp initialize - 2482 ; ret - 2483 - 0984 2484 curselect: - 0984 3ArC6s0A 2485 ld a,(linfo) -a 0987 2486 ld hl,curdsk - 0987 BE 2487 cp (hl) - 0988 C8 2488 ret z ;skip if linfo=curdsk - 0989 77 2489 ld (hl),a ;curdsk=info - 098A C3r60s09 2490 jp select - 2491 ; ret - 2492 - 098D 2493 reselect: ;check current fcb to see if reselection necessary -ua 098D 2494 ld a,true - 098D 32rC6s0A 2495 ld (resel),a ;mark possible reselect - 0990 2ArFCs01 2496 ld hl,(info) - 0993 7E 2497 ld a,(hl) ;drive select code -q 0994 2498 and 11111b ;non zero is auto drive select - 0994 3D 2499 dec a ;drive code normalized to 0..30, or 255 - 0995 32rC6s0A 2500 ld (linfo),a ;save drive code -a 0998 2501 cp 30 - 0998 D2rA9s09 2502 jp nc,noselect - 2503 ;auto select function, save curdsk - 099B 3ArFCs01 2504 ld a,(curdsk) - 099E 32rC6s0A 2505 ld (olddsk),a ;olddsk=curdsk - 09A1 7E 2506 ld a,(hl) - 09A2 32rC6s0A 2507 ld (fcbdsk),a ;save drive code -q 09A5 2508 and 11100000b - 09A5 77 2509 ld (hl),a ;preserve hi bits - 09A6 CDr84s09 2510 call curselect - 09A9 2511 noselect: ;set user code - 09A9 3ArFCs01 2512 ld a,(usrcode) ;0...31 - 09AC 2ArFCs01 2513 ld hl,(info) - 09AF B6 2514 or (hl) - 09B0 77 2515 ld (hl),a - 09B1 C9 2516 ret - 2517 - 2518 ; individual function handlers - 09B2 2519 func12: ;return version number -ua 09B2 2520 ld a,dvers - 09B2 C3rF5s01 2521 jp sta$ret ;lret = dvers (high = 00) - 2522 ; ret - 2523 ; jp goback - 2524 - 09B5 2525 func13: ;reset disk system - initialize to disk 0 -a 09B5 2526 ld hl,0 - 09B5 22rC6s0A 2527 ld (rodsk),hl - 09B8 22rC6s0A 2528 ld (dlog),hl - 09BB AF 2529 xor a - 09BC 32rFCs01 2530 ld (curdsk),a ;note that usrcode remains unchanged -ua 09BF 2531 ld hl,tbuff - 09BF 22rC6s0A 2532 ld (dmaad),hl ;dmaad = tbuff - 09C2 CDr3Cs04 2533 call setdata ;to data dma address - 09C5 C3r60s09 2534 jp select - 2535 ; ret - 2536 ; jp goback - 2537 -o 09C8 2538 func14 equ curselect ;select disk info - 2539 ; ret - 2540 ; jp goback - 2541 - 09C8 2542 func15: ;open file - 09C8 CDrDCs03 2543 call clrmodnum ;clear the module number - 09CB CDr8Ds09 2544 call reselect - 09CE C3r48s06 2545 jp open - 2546 ; ret - 2547 ; jp goback - 2548 - 09D1 2549 func16: ;close file - 09D1 CDr8Ds09 2550 call reselect - 09D4 C3r88s06 2551 jp close - 2552 ; ret - 2553 ; jp goback - 2554 - 09D7 2555 func17: ;search for first occurrence of a file -a 09D7 2556 ld c,0 ;length assuming '?' true - 09D7 EB 2557 ex de,hl ;was lhld info - 09D8 7E 2558 ld a,(hl) -q 09D9 2559 cp '?' ;no reselect if ? - 09D9 CArE6s09 2560 jp z,qselect ;skip reselect if so - 2561 ;normal search - 09DC CDr31s03 2562 call getexta - 09DF 7E 2563 ld a,(hl) -q 09E0 2564 cp '?' ; - 09E0 C4rDCs03 2565 call nz,clrmodnum ;module number zeroed - 09E3 CDr8Ds09 2566 call reselect -ua 09E6 2567 ld c,namlen - 09E6 2568 qselect: - 09E6 CDr47s05 2569 call search - 09E9 C3r45s04 2570 jp dir$to$user ;copy directory entry to user - 2571 ; ret - 2572 ; jp goback - 2573 - 09EC 2574 func18: ;search for next occurrence of a file name - 09EC 2ArC6s0A 2575 ld hl,(searcha) - 09EF 22rFCs01 2576 ld (info),hl - 09F2 CDr8Ds09 2577 call reselect - 09F5 CDr57s05 2578 call searchn - 09F8 C3r45s04 2579 jp dir$to$user ;copy directory entry to user - 2580 ; ret - 2581 ; jp goback - 2582 - 09FB 2583 func19: ;delete a file - 09FB CDr8Ds09 2584 call reselect - 09FE CDrB1s05 2585 call delete - 0A01 C3r32s05 2586 jp copy$dirloc - 2587 ; ret - 2588 ; jp goback - 2589 - 0A04 2590 func20: ;read a file - 0A04 CDr8Ds09 2591 call reselect - 0A07 C3r72s07 2592 jp seqdiskread - 2593 ; jp goback - 2594 - 0A0A 2595 func21: ;write a file - 0A0A CDr8Ds09 2596 call reselect - 0A0D C3rABs07 2597 jp seqdiskwrite - 2598 ; jp goback - 2599 - 0A10 2600 func22: ;make a file - 0A10 CDrDCs03 2601 call clrmodnum - 0A13 CDr8Ds09 2602 call reselect - 0A16 C3rF6s06 2603 jp make - 2604 ; ret - 2605 ; jp goback - 2606 - 0A19 2607 func23: ;rename a file - 0A19 CDr8Ds09 2608 call reselect - 0A1C CDr1Cs06 2609 call rename - 0A1F C3r32s05 2610 jp copy$dirloc - 2611 ; ret - 2612 ; jp goback - 2613 - 0A22 2614 func24: ;return the login vector - 0A22 2ArC6s0A 2615 ld hl,(dlog) - 0A25 C3r4Ds0A 2616 jp sthl$ret - 2617 ; ret - 2618 ; jp goback - 2619 - 0A28 2620 func25: ;return selected disk number - 0A28 3ArFCs01 2621 ld a,(curdsk) - 0A2B C3rF5s01 2622 jp sta$ret - 2623 ; ret - 2624 ; jp goback - 2625 - 0A2E 2626 func26: ;set the subsequent dma address to info - 0A2E EB 2627 ex de,hl ;was lhld info - 0A2F 22rC6s0A 2628 ld (dmaad),hl ;dmaad = info - 0A32 C3r3Cs04 2629 jp setdata ;to data dma address - 2630 ; ret - 2631 ; jp goback - 2632 - 0A35 2633 func27: ;return the login vector address - 0A35 2ArC6s0A 2634 ld hl,(alloca) - 0A38 C3r4Ds0A 2635 jp sthl$ret - 2636 ; ret - 2637 ; jp goback - 2638 -o 0A3B 2639 func28 equ set$ro - 2640 ;write protect current disk - 2641 ; ret - 2642 ; jp goback - 2643 - 0A3B 2644 func29: ;return r/o bit vector - 0A3B 2ArC6s0A 2645 ld hl,(rodsk) - 0A3E C3r4Ds0A 2646 jp sthl$ret - 2647 ; ret - 2648 ; jp goback - 2649 - 0A41 2650 func30: ;set file indicators - 0A41 CDr8Ds09 2651 call reselect - 0A44 CDr38s06 2652 call indicators - 0A47 C3r32s05 2653 jp copy$dirloc ;lret=dirloc - 2654 ; ret - 2655 ; jp goback - 2656 - 0A4A 2657 func31: ;return address of disk parameter block - 0A4A 2ArC6s0A 2658 ld hl,(dpbaddr) - 0A4D 2659 sthl$ret: - 0A4D 22rFCs01 2660 ld (aret),hl - 0A50 C9 2661 ret - 2662 ; jp goback - 2663 - 0A51 2664 func32: ;set user code - 0A51 3ArC6s0A 2665 ld a,(linfo) -q 0A54 2666 cp 0ffh - 0A54 C2r5Ds0A 2667 jp nz,setusrcode - 2668 ;interrogate user code instead - 0A57 3ArFCs01 2669 ld a,(usrcode) - 0A5A C3rF5s01 2670 jp sta$ret ;lret=usrcode - 2671 ; ret - 2672 ; jp goback - 2673 - 0A5D 2674 setusrcode: -q 0A5D 2675 and 1fh - 0A5D 32rFCs01 2676 ld (usrcode),a - 0A60 C9 2677 ret - 2678 ; jp goback - 2679 - 0A61 2680 func33: ;random disk read operation - 0A61 CDr8Ds09 2681 call reselect - 0A64 C3rF4s08 2682 jp randiskread ;to perform the disk read - 2683 ; ret - 2684 ; jp goback - 2685 - 0A67 2686 func34: ;random disk write operation - 0A67 CDr8Ds09 2687 call reselect - 0A6A C3rFBs08 2688 jp randiskwrite ;to perform the disk write - 2689 ; ret - 2690 ; jp goback - 2691 - 0A6D 2692 func35: ;return file size (0-65536) - 0A6D CDr8Ds09 2693 call reselect - 0A70 C3r1Fs09 2694 jp getfilesize - 2695 ; ret - 2696 ; jp goback - 2697 -o 0A73 2698 func36 equ setrandom ;set random record - 2699 ; ret - 2700 ; jp goback - 2701 - 0A73 2ArFCs01 2702 func37: ld hl,(info) - 0A76 7D 2703 ld a,l - 0A77 2F 2704 cpl - 0A78 5F 2705 ld e,a - 0A79 7C 2706 ld a,h - 0A7A 2F 2707 cpl - 0A7B 2ArC6s0A 2708 ld hl,(dlog) - 0A7E A4 2709 and h - 0A7F 57 2710 ld d,a - 0A80 7D 2711 ld a,l - 0A81 A3 2712 and e - 0A82 5F 2713 ld e,a - 0A83 2ArC6s0A 2714 ld hl,(rodsk) - 0A86 EB 2715 ex de,hl - 0A87 22rC6s0A 2716 ld (dlog),hl - 0A8A 7D 2717 ld a,l - 0A8B A3 2718 and e - 0A8C 6F 2719 ld l,a - 0A8D 7C 2720 ld a,h - 0A8E A2 2721 and d - 0A8F 67 2722 ld h,a - 0A90 22rC6s0A 2723 ld (rodsk),hl - 0A93 C9 2724 ret - 2725 - 0A94 2726 goback: ;arrive here at end of processing to return to user - 0A94 3ArC6s0A 2727 ld a,(resel) - 0A97 B7 2728 or a - 0A98 CArAFs0A 2729 jp z,retmon - 2730 ;reselection may have taken place - 0A9B 2ArFCs01 2731 ld hl,(info) -a 0A9E 2732 ld (hl),0 ;fcb(0)=0 - 0A9E 3ArC6s0A 2733 ld a,(fcbdsk) - 0AA1 B7 2734 or a - 0AA2 CArAFs0A 2735 jp z,retmon - 2736 ;restore disk number - 0AA5 77 2737 ld (hl),a ;fcb(0)=fcbdsk - 0AA6 3ArC6s0A 2738 ld a,(olddsk) - 0AA9 32rC6s0A 2739 ld (linfo),a - 0AAC CDr84s09 2740 call curselect - 2741 - 2742 ; return from the disk monitor - 0AAF 2ArFCs01 2743 retmon: ld hl,(entsp) - 0AB2 F9 2744 ld sp,hl ;user stack restored - 0AB3 2ArFCs01 2745 ld hl,(aret) - 0AB6 7D 2746 ld a,l - 0AB7 44 2747 ld b,h ;BA = HL = aret - 0AB8 C9 2748 ret - 2749 -o 0AB9 2750 func38 equ func$ret -o 0AB9 2751 func39 equ func$ret - 0AB9 2752 func40: ;random disk write with zero fill of unallocated block - 0AB9 CDr8Ds09 2753 call reselect -a 0ABC 2754 ld a,2 - 0ABC 32rC6s0A 2755 ld (seqio),a -ua 0ABF 2756 ld c,false - 0ABF CDr8Cs08 2757 call rseek1 - 0AC2 CCrAEs07 2758 call z,diskwrite ;if seek successful - 0AC5 C9 2759 ret - 2760 - 2761 ; data areas - 2762 - 2763 ; initialized data -o 0AC6 2764 efcb: db empty ;0e5=available dir entry -o 0AC6 2765 rodsk: dw 0 ;read only disk vector -o 0AC6 2766 dlog: dw 0 ;logged-in disks -o 0AC6 2767 dmaad: dw tbuff ;initial dma address - 2768 - 2769 ; curtrka - alloca are set upon disk select - 2770 ; (data must be adjacent, do not insert variables) - 2771 ; (address of translate vector, not used) - 0AC6 2772 cdrmaxa: -o 0AC6 2773 ds word ;pointer to cur dir max value - 0AC6 2774 curtrka: -o 0AC6 2775 ds word ;current track address - 0AC6 2776 curreca: -o 0AC6 2777 ds word ;current record address -o 0AC6 2778 buffa: ds word ;pointer to directory dma address - 0AC6 2779 dpbaddr: -o 0AC6 2780 ds word ;current disk parameter block address -o 0AC6 2781 checka: ds word ;current checksum vector address -o 0AC6 2782 alloca: ds word ;current allocation vector address -o 0AC6 2783 addlist equ $-buffa ;address list size - 2784 - 2785 ; sectpt - offset obtained from disk parm block at dpbaddr - 2786 ; (data must be adjacent, do not insert variables) -o 0AC6 2787 sectpt: ds word ;sectors per track -o 0AC6 2788 blkshf: ds byte ;block shift factor -o 0AC6 2789 blkmsk: ds byte ;block mask -o 0AC6 2790 extmsk: ds byte ;extent mask -o 0AC6 2791 maxall: ds word ;maximum allocation number -o 0AC6 2792 dirmax: ds word ;largest directory number -o 0AC6 2793 dirblk: ds word ;reserved allocation bits for directory -o 0AC6 2794 chksiz: ds word ;size of checksum vector -o 0AC6 2795 offset: ds word ;offset tracks at beginning -o 0AC6 2796 dpblist equ $-sectpt ;size of area - 2797 - 2798 ; local variables -o 0AC6 2799 tranv: ds word ;address of translate vector - 0AC6 2800 fcb$copied: -o 0AC6 2801 ds byte ;set true if copy$fcb called -o 0AC6 2802 rmf: ds byte ;read mode flag for open$reel -o 0AC6 2803 dirloc: ds byte ;directory flag in rename, etc. -o 0AC6 2804 seqio: ds byte ;1 if sequential i/o -o 0AC6 2805 linfo: ds byte ;low(info) -o 0AC6 2806 dminx: ds byte ;local for diskwrite - 0AC6 2807 searchl: -o 0AC6 2808 ds byte ;search length - 0AC6 2809 searcha: -o 0AC6 2810 ds word ;search address -o 0AC6 2811 tinfo: ds word ;temp for info in "make" -o 0AC6 2812 single: ds byte ;set true if single byte allocation map -o 0AC6 2813 resel: ds byte ;reselection flag -o 0AC6 2814 olddsk: ds byte ;disk on entry to bdos -o 0AC6 2815 fcbdsk: ds byte ;disk named in fcb -o 0AC6 2816 rcount: ds byte ;record count in current fcb -o 0AC6 2817 extval: ds byte ;extent number and extmsk - 0AC6 2818 vrecord: -o 0AC6 2819 ds word ;current virtual record - 0AC6 2820 arecord: -o 0AC6 2821 ds word ;current actual record - 0AC6 2822 arecord1: -o 0AC6 2823 ds word ;current actual block# * blkmsk - 2824 - 2825 ; local variables for directory access -o 0AC6 2826 dptr: ds byte ;directory pointer 0,1,2,3 -o 0AC6 2827 dcnt: ds word ;directory counter 0,1,...,dirmax -o 0AC6 2828 drec: ds word ;directory record 0,1,...,dirmax/4 - 2829 - 2830 ;bios equ ($ and 0ff00h)+100h;next module - 2831 - 2832 ;;dwg;; end - 2833 - 2834 ;; dwg ; end dri source code here - 2835 - 0AC6 2836 _bdos_end:: - 2837 .area _CODE - 2838 .area _CABS diff --git a/doug/src/dribdos.mac b/doug/src/dribdos.mac deleted file mode 100755 index b0a8f6d4..00000000 --- a/doug/src/dribdos.mac +++ /dev/null @@ -1,2775 +0,0 @@ - title 'Bdos Interface, Bdos, Version 2.2 Feb, 1980' - - .Z80 - aseg - org 100h - maclib MEMCFG.LIB ; define configuration parameters - .phase bdosph -bios equ biosph - -;***************************************************************** -;***************************************************************** -;** ** -;** B a s i c D i s k O p e r a t i n g S y s t e m ** -;** I n t e r f a c e M o d u l e ** -;** ** -;***************************************************************** -;***************************************************************** - -; Copyright (c) 1978, 1979, 1980 -; Digital Research -; Box 579, Pacific Grove -; California - - -; 20 january 1980 - -ssize equ 24 ;24 level stack - -; low memory locations -reboot equ 0000h ;reboot system -ioloc equ 0003h ;i/o byte location -bdosa equ 0006h ;address field of jp BDOS - -; bios access constants -bootf defl bios+3*0 ;cold boot function -wbootf defl bios+3*1 ;warm boot function -constf defl bios+3*2 ;console status function -coninf defl bios+3*3 ;console input function -conoutf defl bios+3*4 ;console output function -listf defl bios+3*5 ;list output function -punchf defl bios+3*6 ;punch output function -readerf defl bios+3*7 ;reader input function -homef defl bios+3*8 ;disk home function -seldskf defl bios+3*9 ;select disk function -settrkf defl bios+3*10 ;set track function -setsecf defl bios+3*11 ;set sector function -setdmaf defl bios+3*12 ;set dma function -readf defl bios+3*13 ;read disk function -writef defl bios+3*14 ;write disk function -liststf defl bios+3*15 ;list status function -sectran defl bios+3*16 ;sector translate - -; equates for non graphic characters -ctlc equ 03h ;control c -ctle equ 05h ;physical eol -ctlh equ 08h ;backspace -ctlp equ 10h ;prnt toggle -ctlr equ 12h ;repeat line -ctls equ 13h ;stop/start screen -ctlu equ 15h ;line delete -ctlx equ 18h ;=ctl-u -ctlz equ 1ah ;end of file -rubout equ 7fh ;char delete -tab equ 09h ;tab char -cr equ 0dh ;carriage return -lf equ 0ah ;line feed -ctl equ 5eh ;up arrow - - db 0,0,0,0,0,0 - -; enter here from the user's program with function number in c, -; and information address in d,e - jp bdose ;past parameter block - -; ************************************************ -; *** relative locations 0009 - 000e *** -; ************************************************ -pererr: dw persub ;permanent error subroutine -selerr: dw selsub ;select error subroutine -roderr: dw rodsub ;ro disk error subroutine -roferr: dw rofsub ;ro file error subroutine - - -bdose: ex de,hl ;arrive here from user programs - ld (info),hl - ex de,hl ;info=DE, DE=info - ld a,e - ld (linfo),a ;linfo = low(info) - don't equ - ld hl,0 - ld (aret),hl ;return value defaults to 0000 - ;save user's stack pointer, set to local stack - add hl,sp - ld (entsp),hl ;entsp = stackptr - ld sp,lstack ;local stack setup - xor a - ld (fcbdsk),a - ld (resel),a ;fcbdsk,resel=false - ld hl,goback ;return here after all functions - push hl ;jmp goback equivalent to ret - ld a,c - cp nfuncs - ret nc ;skip if invalid # - ld c,e ;possible output character to C - ld hl,functab - ld e,a - ld d,0 ;DE=func, HL=.ciotab - add hl,de - add hl,de - ld e,(hl) - inc hl - ld d,(hl) ;DE=functab(func) - ld hl,(info) ;info in DE for later xchg - ex de,hl - jp (hl) ;dispatched - -; dispatch table for functions -functab: - dw wbootf, func1, func2, func3 - dw punchf, listf, func6, func7 - dw func8, func9, func10,func11 -diskf equ ($-functab)/2 ;disk funcs - dw func12,func13,func14,func15 - dw func16,func17,func18,func19 - dw func20,func21,func22,func23 - dw func24,func25,func26,func27 - dw func28,func29,func30,func31 - dw func32,func33,func34,func35 - dw func36,func37,func38,func39 - dw func40 -nfuncs equ ($-functab)/2 - - -; error subroutines -persub: ld hl,permsg ;report permanent error - call errflg ;to report the error - cp ctlc - jp z,reboot ;reboot if response is ctlc - ret ;and ignore the error - -selsub: ld hl,selmsg ;report select error - jp wait$err ;wait console before boot - -rodsub: ld hl,rodmsg ;report write to read/only disk - jp wait$err ;wait console - -rofsub: ;report read/only file - ld hl,rofmsg ;drop through to wait for console - -wait$err: ;wait for response before boot - call errflg - jp reboot - -; error messages -dskmsg: db 'Bdos Err On ' -dskerr: db ' : $' ;filled in by errflg -permsg: db 'Bad Sector$' -selmsg: db 'Select$' -rofmsg: db 'File ' -rodmsg: db 'R/O$' - - -errflg: push hl ;report error to console, message address in HL - call crlf ;stack mssg address, new line - ld a,(curdsk) - add a,'A' - ld (dskerr),a ;current disk name - ld bc,dskmsg - call print ;the error message - pop bc - call print ;error mssage tail -; jp conin ;to get the input character - ;(drop through to conin) -; ret - - -; console handlers -conin: ld hl,kbchar ;read console character to A - ld a,(hl) - ld (hl),0 - or a - ret nz - ;no previous keyboard character ready - jp coninf ;get character externally -; ret -conech: call conin ;read character with echo - call echoc - ret c ;echo character? - ;character must be echoed before return - push af - ld c,a - call tabout - pop af - ret ;with character in A - -echoc: ;echo character if graphic - cp cr ;cr, lf, tab, or backspace - ret z ;carriage return? - cp lf - ret z ;line feed? - cp tab - ret z ;tab? - cp ctlh - ret z ;backspace? - cp ' ' - ret ;carry set if not graphic - -conbrk: ;check for character ready - ld a,(kbchar) - or a - jp nz,conb1 ;skip if active kbchar - ;no active kbchar, check external break - call constf - and 1 - ret z ;return if no char ready - ;character ready, read it - call coninf ;to A - cp ctls - jp nz,conb0 ;check stop screen function - ;found ctls, read next character - call coninf ;to A - cp ctlc - jp z,reboot ;ctlc implies re-boot - ;not a reboot, act as if nothing has happened - xor a - ret ;with zero in accumulator -conb0: - ;character in accum, save it - ld (kbchar),a -conb1: - ;return with true set in accumulator - ld a,1 - ret - -conout: ;compute character position/write console char from C - ;compcol = true if computing column position - ld a,(compcol) - or a - jp nz,compout - ;write the character, then compute the column - ;write console character from C - push bc - call conbrk ;check for screen stop function - pop bc - push bc ;recall/save character - call conoutf ;externally, to console - pop bc - push bc ;recall/save character - ;may be copying to the list device - ld a,(listcp) - or a - call nz,listf ;to printer, if so - pop bc ;recall the character -compout: - ld a,c ;recall the character - ;and compute column position - ld hl,column ;A = char, HL = .column - cp rubout - ret z ;no column change if nulls - inc (hl) ;column = column + 1 - cp ' ' - ret nc ;return if graphic - ;not graphic, reset column position - dec (hl) ;column = column - 1 - ld a,(hl) - or a - ret z ;return if at zero - ;not at zero, may be backspace or end line - ld a,c ;character back to A - cp ctlh - jp nz,notbacksp - ;backspace character - dec (hl) ;column = column - 1 - ret - -notbacksp: ;not a backspace character, eol? - cp lf - ret nz ;return if not - ;end of line, column = 0 - ld (hl),0 ;column = 0 - ret - -ctlout: ;send C character with possible preceding up-arrow - ld a,c - call echoc ;cy if not graphic (or special case) - jp nc,tabout ;skip if graphic, tab, cr, lf, or ctlh - ;send preceding up arrow - push af - ld c,ctl - call conout ;up arrow - pop af - or 40h ;becomes graphic letter - ld c,a ;ready to print - ;(drop through to tabout) - -tabout: ;expand tabs to console - ld a,c - cp tab - jp nz,conout ;direct to conout if not - ;tab encountered, move to next tab position -tab0: ld c,' ' - call conout ;another blank - ld a,(column) - and 111b ;column mod 8 = 0 ? - jp nz,tab0 ;back for another if not - ret - -backup: ;back-up one screen position - call pctlh - ld c,' ' - call conoutf -; (drop through to pctlh) -pctlh: ;send ctlh to console without affecting column count - ld c,ctlh - jp conoutf -; ret -crlfp: ;print #, cr, lf for ctlx, ctlu, ctlr functions - ;then move to strtcol (starting column) - ld c,'#' - call conout - call crlf ;column = 0, move to position strtcol -crlfp0: ld a,(column) - ld hl,strtcol - cp (hl) - ret nc ;stop when column reaches strtcol - ld c,' ' - call conout ;print blank - jp crlfp0 - -crlf: ld c,cr ;carriage return line feed sequence - call conout - ld c,lf - jp conout -; ret -print: ld a,(bc) ;print message until M(BC) = '$' - cp '$' - ret z ;stop on $ - ;more to print - inc bc - push bc - ld c,a ;char to C - call tabout ;another character printed - pop bc - jp print - -read: ;read to info address (max length, current length, buffer) - ld a,(column) - ld (strtcol),a ;save start for ctl-x, ctl-h - ld hl,(info) - ld c,(hl) - inc hl - push hl - ld b,0 - ;B = current buffer length, - ;C = maximum buffer length, - ;HL= next to fill - 1 -readnx: ;read next character, BC, HL active - push bc - push hl ;blen, cmax, HL saved -readn0: call conin ;next char in A - and 7fh ;mask parity bit - pop hl - pop bc ;reactivate counters - cp cr - jp z,readen ;end of line? - cp lf - jp z,readen ;also end of line - cp ctlh - jp nz,noth ;backspace? - ;do we have any characters to back over? - ld a,b - or a - jp z,readnx - ;characters remain in buffer, backup one - dec b ;remove one character - ld a,(column) - ld (compcol),a ;col > 0 - ;compcol > 0 marks repeat as length compute - jp linelen ;uses same code as repeat - -noth: ;not a backspace - cp rubout - jp nz,notrub ;rubout char? - ;rubout encountered, rubout if possible - ld a,b - or a - jp z,readnx ;skip if len=0 - ;buffer has characters, resend last char - ld a,(hl) - dec b - dec hl ;A = last char - ;blen=blen-1, next to fill - 1 decremented - jp rdech1 ;act like this is an echo - -notrub: ;not a rubout character, check end line - cp ctle - jp nz,note ;physical end line? - ;yes, save active counters and force eol - push bc - push hl - call crlf - xor a - ld (strtcol),a ;start position = 00 - jp readn0 ;for another character - -note: ;not end of line, list toggle? - cp ctlp - jp nz,notp ;skip if not ctlp - ;list toggle - change parity - push hl ;save next to fill - 1 - ld hl,listcp ;HL=.listcp flag - ld a,1 - sub (hl) ;True-listcp - ld (hl),a ;listcp = not listcp - pop hl - jp readnx ;for another char - -notp: ;not a ctlp, line delete? - cp ctlx - jp nz,notx - pop hl ;discard start position - ;loop while column > strtcol -backx: ld a,(strtcol) - ld hl,column - cp (hl) - jp nc,read ;start again - dec (hl) ;column = column - 1 - call backup ;one position - jp backx - -notx: ;not a control x, control u? - ;not control-X, control-U? - cp ctlu - jp nz,notu ;skip if not - ;delete line (ctlu) - call crlfp ;physical eol - pop hl ;discard starting position - jp read ;to start all over - -notu: ;not line delete, repeat line? - cp ctlr - jp nz,notr -linelen: ;repeat line, or compute line len (ctlh) - ;if compcol > 0 - push bc - call crlfp ;save line length - pop bc - pop hl - push hl - push bc - ;bcur, cmax active, beginning buff at HL -rep0: ld a,b - or a - jp z,rep1 ;count len to 00 - inc hl - ld c,(hl) ;next to print - dec b - push bc - push hl ;count length down - call ctlout ;character echoed - pop hl - pop bc ;recall remaining count - jp rep0 ;for the next character - -rep1: ;end of repeat, recall lengths - ;original BC still remains pushed - push hl ;save next to fill - ld a,(compcol) - or a ;>0 if computing length - jp z,readn0 ;for another char if so - ;column position computed for ctlh - ld hl,column - sub (hl) ;diff > 0 - ld (compcol),a ;count down below - ;move back compcol-column spaces -backsp: ;move back one more space - call backup ;one space - ld hl,compcol - dec (hl) - jp nz,backsp - jp readn0 ;for next character - -notr: ;not a ctlr, place into buffer -rdecho: inc hl - ld (hl),a ;character filled to mem - inc b ;blen = blen + 1 -rdech1: ;look for a random control character - push bc - push hl ;active values saved - ld c,a ;ready to print - call ctlout ;may be up-arrow C - pop hl - pop bc - ld a,(hl) ;recall char - cp ctlc ;set flags for reboot test - ld a,b ;move length to A - jp nz,notc ;skip if not a control c - cp 1 ;control C, must be length 1 - jp z,reboot ;reboot if blen = 1 - ;length not one, so skip reboot -notc: ;not reboot, are we at end of buffer? - cp c - jp c,readnx ;go for another if not -readen: ;end of read operation, store blen - pop hl - ld (hl),b ;M(current len) = B - ld c,cr - jp conout ;return carriage -; ret -func1: ;return console character with echo - call conech - jp sta$ret - -func2 equ tabout - ;write console character with tab expansion - -func3: ;return reader character - call readerf - jp sta$ret - -;func4: equated to punchf - ;write punch character - -;func5: equated to listf - ;write list character - ;write to list device - -func6: ;direct console i/o - read if 0ffh - ld a,c - inc a - jp z,dirinp ;0ffh => 00h, means input mode - inc a - jp z,constf ;0feH in C for status - ;direct output function - jp conoutf - -dirinp: call constf ;status check - or a - jp z,retmon ;skip, return 00 if not ready - ;character is ready, get it - call coninf ;to A - jp sta$ret - -func7: ;return io byte - ld a,(ioloc) - jp sta$ret - -func8: ;set i/o byte - ld hl,ioloc - ld (hl),c - ret ;jmp goback - -func9: ;write line until $ encountered - ex de,hl ;was lhld info - ld c,l - ld b,h ;BC=string address - jp print ;out to console - -func10 equ read - ;read a buffered console line - -func11: ;check console status - call conbrk - ;(drop through to sta$ret) -sta$ret: ;store the A register to aret - ld (aret),a -func$ret: - ret ;jmp goback (pop stack for non cp/m functions) - -setlret1: ;set lret = 1 - ld a,1 - jp sta$ret - - - -; data areas - -compcol: - db 0 ;true if computing column position -strtcol: - db 0 ;starting column position after read -column: db 0 ;column position -listcp: db 0 ;listing toggle -kbchar: db 0 ;initial key char = 00 -entsp: ds 2 ;entry stack pointer - ds ssize*2 ;stack size -lstack: -; end of Basic I/O System - -;***************************************************************** -;***************************************************************** - -; common values shared between bdosi and bdos -usrcode: - db 0 ;current user number -curdsk: db 0 ;current disk number -info: ds 2 ;information address -aret: ds 2 ;address value to return -lret equ aret ;low(aret) - -;***************************************************************** -;***************************************************************** -;** ** -;** B a s i c D i s k O p e r a t i n g S y s t e m ** -;** ** -;***************************************************************** -;***************************************************************** - -dvers equ 22h ;version 2.2 -; module addresses - -; literal constants -true equ 0ffh ;constant true -false equ 000h ;constant false -enddir equ 0ffffh ;end of directory -byte equ 1 ;number of bytes for "byte" type -word equ 2 ;number of bytes for "word" type - -; fixed addresses in low memory -tfcb equ 005ch ;default fcb location -tbuff equ 0080h ;default buffer location - -; fixed addresses referenced in bios module are -; pererr (0009), selerr (000c), roderr (000f) - -; error message handlers - -;per$error: ;report permanent error to user -; ld hl,pererr -; jp goerr - -;rod$error: ;report read/only disk error -; ld hl,roderr -; jp goerr - -;rof$error: ;report read/only file error -; ld hl,roferr -; jp goerr - -sel$error: ;report select error - ld hl,selerr - - -goerr: ;HL = .errorhandler, call subroutine - ld e,(hl) - inc hl - ld d,(hl) ;address of routine in DE - ex de,hl - jp (hl) ;to subroutine - - - -; local subroutines for bios interface - -move: ;move data length of length C from source DE to - ;destination given by HL - inc c ;in case it is zero -move0: dec c - ret z ;more to move - ld a,(de) - ld (hl),a ;one byte moved - inc de - inc hl ;to next byte - jp move0 - -selectdisk: ;select the disk drive given by curdsk, and fill - ;the base addresses curtrka - alloca, then fill - ;the values of the disk parameter block - ld a,(curdsk) - ld c,a ;current disk# to c - ;lsb of e = 0 if not yet logged - in - call seldskf ;HL filled by call - ;HL = 0000 if error, otherwise disk headers - ld a,h - or l - ret z ;return with 0000 in HL and z flag - ;disk header block address in hl - ld e,(hl) - inc hl - ld d,(hl) - inc hl ;DE=.tran - ld (cdrmaxa),hl - inc hl - inc hl ;.cdrmax - ld (curtrka),hl - inc hl - inc hl ;HL=.currec - ld (curreca),hl - inc hl - inc hl ;HL=.buffa - ;DE still contains .tran - ex de,hl - ld (tranv),hl ;.tran vector - ld hl,buffa ;DE= source for move, HL=dest - ld c,addlist - call move ;addlist filled - ;now fill the disk parameter block - ld hl,(dpbaddr) - ex de,hl ;DE is source - ld hl,sectpt ;HL is destination - ld c,dpblist - call move ;data filled - ;now set single/double map mode - ld hl,(maxall) ;largest allocation number - ld a,h ;00 indicates < 255 - ld hl,single - ld (hl),true ;assume a=00 - or a - jp z,retselect - ;high order of maxall not zero, use double dm - ld (hl),false -retselect: - ld a,true - or a - ret ;select disk function ok - -home: ;move to home position, then offset to start of dir - call homef ;move to track 00, sector 00 reference - ;lxi h,offset ;mov c,m ;inx h ;mov b,m ;call settrkf - ;first directory position selected - xor a ;constant zero to accumulator - ld hl,(curtrka) - ld (hl),a - inc hl - ld (hl),a ;curtrk=0000 - ld hl,(curreca) - ld (hl),a - inc hl - ld (hl),a ;currec=0000 - ;curtrk, currec both set to 0000 - ret - -rdbuff: ;read buffer and check condition - call readf ;current drive, track, sector, dma - jp diocomp ;check for i/o errors - -wrbuff: ;write buffer and check condition - ;write type (wrtype) is in register C - ;wrtype = 0 => normal write operation - ;wrtype = 1 => directory write operation - ;wrtype = 2 => start of new block - call writef ;current drive, track, sector, dma -diocomp: ;check for disk errors - or a - ret z - ld hl,pererr - jp goerr - -seek$dir: ;seek the record containing the current dir entry - ld hl,(dcnt) ;directory counter to HL - ld c,dskshf - call hlrotr ;value to HL - ld (arecord),hl - ld (drec),hl ;ready for seek -; jp seek -; ret - - -seek: ;seek the track given by arecord (actual record) - ;local equates for registers - ;load the registers from memory - ld hl,arecord - ld c,(hl) - inc hl - ld b,(hl) - ld hl,(curreca) - ld e,(hl) - inc hl - ld d,(hl) - ld hl,(curtrka) - ld a,(hl) - inc hl - ld h,(hl) - ld l,a - ;loop while arecord < currec -seek0: ld a,c - sub e - ld a,b - sbc a,d - jp nc,seek1 ;skip if arecord >= currec - ;currec = currec - sectpt - push hl - ld hl,(sectpt) - ld a,e - sub l - ld e,a - ld a,d - sbc a,h - ld d,a - pop hl - ;curtrk = curtrk - 1 - dec hl - jp seek0 ;for another try - -seek1: ;look while arecord >= (t:=currec + sectpt) - push hl - ld hl,(sectpt) - add hl,de ;HL = currec+sectpt - jp c,seek2 ;can be > FFFFH - ld a,c - sub l - ld a,b - sbc a,h - jp c,seek2 ;skip if t > arecord - ;currec = t - ex de,hl - ;curtrk = curtrk + 1 - pop hl - inc hl - jp seek1 ;for another try - -seek2: pop hl - ;arrive here with updated values in each register - push bc - push de - push hl ;to stack for later - ;stack contains (lowest) BC=arecord, DE=currec, HL=curtrk - ex de,hl - ld hl,(offset) - add hl,de ;HL = curtrk+offset - ld b,h - ld c,l - call settrkf ;track set up - ;note that BC - curtrk is difference to move in bios - pop de ;recall curtrk - ld hl,(curtrka) - ld (hl),e - inc hl - ld (hl),d ;curtrk updated - ;now compute sector as arecord-currec - pop de ;recall currec - ld hl,(curreca) - ld (hl),e - inc hl - ld (hl),d - pop bc ;BC=arecord, DE=currec - ld a,c - sub e - ld c,a - ld a,b - sbc a,d - ld b,a - ld hl,(tranv) - ex de,hl ;BC=sector#, DE=.tran - call sectran ;HL = tran(sector) - ld c,l - ld b,h ;BC = tran(sector) - jp setsecf ;sector selected -; ret - -; file control block (fcb) constants -empty equ 0e5h ;empty directory entry -lstrec equ 127 ;last record# in extent -recsiz equ 128 ;record size -fcblen equ 32 ;file control block size -dirrec equ recsiz/fcblen ;directory elts / record -dskshf equ 2 ;log2(dirrec) -dskmsk equ dirrec-1 -fcbshf equ 5 ;log2(fcblen) - -extnum equ 12 ;extent number field -maxext equ 31 ;largest extent number -ubytes equ 13 ;unfilled bytes field -modnum equ 14 ;data module number -maxmod equ 15 ;largest module number -fwfmsk equ 80h ;file write flag is high order modnum -namlen equ 15 ;name length -reccnt equ 15 ;record count field -dskmap equ 16 ;disk map field -lstfcb equ fcblen-1 -nxtrec equ fcblen -ranrec equ nxtrec+1 ;random record field (2 bytes) - -; reserved file indicators -rofile equ 9 ;high order of first type char -invis equ 10 ;invisible file in dir command -; equ 11 ;reserved - -; utility functions for file access - -dm$position: ;compute disk map position for vrecord to HL - ld hl,blkshf - ld c,(hl) ;shift count to C - ld a,(vrecord) ;current virtual record to A -dmpos0: or a - rra - dec c - jp nz,dmpos0 - ;A = shr(vrecord,blkshf) = vrecord/2**(sect/block) - ld b,a ;save it for later addition - ld a,8 - sub (hl) ;8-blkshf to accumulator - ld c,a ;extent shift count in register c - ld a,(extval) ;extent value ani extmsk -dmpos1: - ;blkshf = 3,4,5,6,7, C=5,4,3,2,1 - ;shift is 4,3,2,1,0 - dec c - jp z,dmpos2 - or a - rla - jp dmpos1 - -dmpos2: ;arrive here with A = shl(ext and extmsk,7-blkshf) - add a,b ;add the previous shr(vrecord,blkshf) value - ;A is one of the following values, depending upon alloc - ;bks blkshf - ;1k 3 v/8 + extval * 16 - ;2k 4 v/16+ extval * 8 - ;4k 5 v/32+ extval * 4 - ;8k 6 v/64+ extval * 2 - ;16k 7 v/128+extval * 1 - ret ;with dm$position in A - -getdm: ;return disk map value from position given by BC - ld hl,(info) ;base address of file control block - ld de,dskmap - add hl,de ;HL =.diskmap - add hl,bc ;index by a single byte value - ld a,(single) ;single byte/map entry? - or a - jp z,getdmd ;get disk map single byte - ld l,(hl) - ld h,0 - ret ;with HL=00bb -getdmd: - add hl,bc ;HL=.fcb(dm+i*2) - ;double precision value returned - ld e,(hl) - inc hl - ld d,(hl) - ex de,hl - ret - -index: ;compute disk block number from current fcb - call dm$position ;0...15 in register A - ld c,a - ld b,0 - call getdm ;value to HL - ld (arecord),hl - ret - -allocated: ;called following index to see if block allocated - ld hl,(arecord) - ld a,l - or h - ret - -atran: ;compute actual record address, assuming index called - ld a,(blkshf) ;shift count to reg A - ld hl,(arecord) -atran0: add hl,hl - dec a - jp nz,atran0 ;shl(arecord,blkshf) - ld (arecord1),hl ;save shifted block # - ld a,(blkmsk) - ld c,a ;mask value to C - ld a,(vrecord) - and c ;masked value in A - or l - ld l,a ;to HL - ld (arecord),hl ;arecord=HL or (vrecord and blkmsk) - ret - -getexta: ;get current extent field address to A - ld hl,(info) - ld de,extnum - add hl,de ;HL=.fcb(extnum) - ret - -getfcba: ;compute reccnt and nxtrec addresses for get/setfcb - ld hl,(info) - ld de,reccnt - add hl,de - ex de,hl ;DE=.fcb(reccnt) - ld hl,nxtrec-reccnt - add hl,de ;HL=.fcb(nxtrec) - ret - -getfcb: ;set variables from currently addressed fcb - call getfcba ;addresses in DE, HL - ld a,(hl) - ld (vrecord),a ;vrecord=fcb(nxtrec) - ex de,hl - ld a,(hl) - ld (rcount),a ;rcount=fcb(reccnt) - call getexta ;HL=.fcb(extnum) - ld a,(extmsk) ;extent mask to a - and (hl) ;fcb(extnum) and extmsk - ld (extval),a - ret - -setfcb: ;place values back into current fcb - call getfcba ;addresses to DE, HL - ld a,(seqio) - cp 02 - jp nz,setfcb1 - xor a ;check ranfill -setfcb1: - ld c,a ;=1 if sequential i/o - ld a,(vrecord) - add a,c - ld (hl),a ;fcb(nxtrec)=vrecord+seqio - ex de,hl - ld a,(rcount) - ld (hl),a ;fcb(reccnt)=rcount - ret - -hlrotr: ;hl rotate right by amount C - inc c ;in case zero -hlrotr0: - dec c - ret z ;return when zero - ld a,h - or a - rra - ld h,a ;high byte - ld a,l - rra - ld l,a ;low byte - jp hlrotr0 - -compute$cs: ;compute checksum for current directory buffer - ld c,recsiz ;size of directory buffer - ld hl,(buffa) ;current directory buffer - xor a ;clear checksum value -computecs0: - add a,(hl) - inc hl - dec c ;cs=cs+buff(recsiz-C) - jp nz,computecs0 - ret ;with checksum in A - -hlrotl: ;rotate the mask in HL by amount in C - inc c ;may be zero -hlrotl0: - dec c - ret z ;return if zero - add hl,hl - jp hlrotl0 - -set$cdisk: ;set a "1" value in curdsk position of BC - push bc ;save input parameter - ld a,(curdsk) - ld c,a ;ready parameter for shift - ld hl,1 ;number to shift - call hlrotl ;HL = mask to integrate - pop bc ;original mask - ld a,c - or l - ld l,a - ld a,b - or h - ld h,a ;HL = mask or rol(1,curdsk) - ret - -nowrite: ;return true if dir checksum difference occurred - ld hl,(rodsk) - ld a,(curdsk) - ld c,a - call hlrotr - ld a,l - and 1b - ret ;non zero if nowrite - -set$ro: ;set current disk to read only - ld hl,rodsk - ld c,(hl) - inc hl - ld b,(hl) - call set$cdisk ;sets bit to 1 - ld (rodsk),hl - ;high water mark in directory goes to max - ld hl,(dirmax) - inc hl - ex de,hl ;DE = directory max - ld hl,(cdrmaxa) ;HL = .cdrmax - ld (hl),e - inc hl - ld (hl),d ;cdrmax = dirmax - ret - -check$rodir: ;check current directory element for read/only status - call getdptra ;address of element - -check$rofile: ;check current buff(dptr) or fcb(0) for r/o status - ld de,rofile - add hl,de ;offset to ro bit - ld a,(hl) - rla - ret nc ;return if not set - ld hl,roferr - jp goerr -; jp rof$error ;exit to read only disk message - - -check$write: ;check for write protected disk - call nowrite - ret z ;ok to write if not rodsk - ld hl,roderr - jp goerr -; jp rod$error ;read only disk error - -getdptra: ;compute the address of a directory element at - ;positon dptr in the buffer - ld hl,(buffa) - ld a,(dptr) -addh: ;HL = HL + A - add a,l - ld l,a - ret nc - ;overflow to H - inc h - ret - - -getmodnum: ;compute the address of the module number - ;bring module number to accumulator - ;(high order bit is fwf (file write flag) - ld hl,(info) - ld de,modnum - add hl,de ;HL=.fcb(modnum) - ld a,(hl) - ret ;A=fcb(modnum) - -clrmodnum: ;clear the module number field for user open/make - call getmodnum - ld (hl),0 ;fcb(modnum)=0 - ret - -setfwf: call getmodnum ;HL=.fcb(modnum), A=fcb(modnum) - ;set fwf (file write flag) to "1" - or fwfmsk - ld (hl),a ;fcb(modnum)=fcb(modnum) or 80h - ;also returns non zero in accumulator - ret - - -compcdr: ;return cy if cdrmax > dcnt - ld hl,(dcnt) - ex de,hl ;DE = directory counter - ld hl,(cdrmaxa) ;HL=.cdrmax - ld a,e - sub (hl) ;low(dcnt) - low(cdrmax) - inc hl ;HL = .cdrmax+1 - ld a,d - sbc a,(hl) ;hig(dcnt) - hig(cdrmax) - ;condition dcnt - cdrmax produces cy if cdrmax>dcnt - ret - -setcdr: ;if not (cdrmax > dcnt) then cdrmax = dcnt+1 - call compcdr - ret c ;return if cdrmax > dcnt - ;otherwise, HL = .cdrmax+1, DE = dcnt - inc de - ld (hl),d - dec hl - ld (hl),e - ret - -subdh: ;compute HL = DE - HL - ld a,e - sub l - ld l,a - ld a,d - sbc a,h - ld h,a - ret - -newchecksum: - ld c,true ;drop through to compute new checksum -checksum: ;compute current checksum record and update the - ;directory element if C=true, or check for = if not - ;drec < chksiz? - ld hl,(drec) - ex de,hl - ld hl,(chksiz) - call subdh ;DE-HL - ret nc ;skip checksum if past checksum vector size - ;drec < chksiz, so continue - push bc ;save init flag - call compute$cs ;check sum value to A - ld hl,(checka) ;address of check sum vector - ex de,hl - ld hl,(drec) ;value of drec - add hl,de ;HL = .check(drec) - pop bc ;recall true=0ffh or false=00 to C - inc c ;0ffh produces zero flag - jp z,initial$cs - ;not initializing, compare - cp (hl) ;compute$cs=check(drec)? - ret z ;no message if ok - ;checksum error, are we beyond - ;the end of the disk? - call compcdr - ret nc ;no message if so - call set$ro ;read/only disk set - ret - -initial$cs: ;initializing the checksum - ld (hl),a - ret - - -wrdir: ;write the current directory entry, set checksum - call newchecksum ;initialize entry - call setdir ;directory dma - ld c,1 ;indicates a write directory operation - call wrbuff ;write the buffer - jp setdata ;to data dma address -; ret -rd$dir: ;read a directory entry into the directory buffer - call setdir ;directory dma - call rdbuff ;directory record loaded - ;jmp setdata to data dma address -; ret -setdata: ;set data dma address - ld hl,dmaad - jp setdma ;to complete the call - -setdir: ;set directory dma address - ld hl,buffa ;jmp setdma to complete call - -setdma: ;HL=.dma address to set (i.e., buffa or dmaad) - ld c,(hl) - inc hl - ld b,(hl) ;parameter ready - jp setdmaf - -dir$to$user: ;copy the directory entry to the user buffer - ;after call to search or searchn by user code - ld hl,(buffa) - ex de,hl ;source is directory buffer - ld hl,(dmaad) ;destination is user dma address - ld c,recsiz ;copy entire record - jp move -; ret - -end$of$dir: ;return zero flag if at end of directory, non zero - ;if not at end (end of dir if dcnt = 0ffffh) - ld hl,dcnt - ld a,(hl) ;may be 0ffh - inc hl - cp (hl) ;low(dcnt) = high(dcnt)? - ret nz ;non zero returned if different - ;high and low the same, = 0ffh? - inc a ;0ffh becomes 00 if so - ret - -set$end$dir: ;set dcnt to the end of the directory - ld hl,enddir - ld (dcnt),hl - ret - -read$dir: ;read next directory entry, with C=true if initializing - ld hl,(dirmax) - ex de,hl ;in preparation for subtract - ld hl,(dcnt) - inc hl - ld (dcnt),hl ;dcnt=dcnt+1 - ;continue while dirmax >= dcnt (dirmax-dcnt no cy) - call subdh ;DE-HL - jp nc,read$dir0 - ;yes, set dcnt to end of directory - jp set$end$dir -; ret - -read$dir0: ;not at end of directory, seek next element - ;initialization flag is in C - ld a,(dcnt) - and dskmsk ;low(dcnt) and dskmsk - ld b,fcbshf ;to multiply by fcb size -read$dir1: - add a,a - dec b - jp nz,read$dir1 - ;A = (low(dcnt) and dskmsk) shl fcbshf - ld (dptr),a ;ready for next dir operation - or a - ret nz ;return if not a new record - push bc ;save initialization flag C - call seek$dir ;seek proper record - call rd$dir ;read the directory record - pop bc ;recall initialization flag - jp checksum ;checksum the directory elt -; ret - - -getallocbit: ;given allocation vector position BC, return with byte - ;containing BC shifted so that the least significant - ;bit is in the low order accumulator position. HL is - ;the address of the byte for possible replacement in - ;memory upon return, and D contains the number of shifts - ;required to place the returned value back into position - ld a,c - and 111b - inc a - ld e,a - ld d,a - ;d and e both contain the number of bit positions to shift - ld a,c - rrca - rrca - rrca - and 11111b - ld c,a ;C shr 3 to C - ld a,b - add a,a - add a,a - add a,a - add a,a - add a,a ;B shl 5 - or c - ld c,a ;bbbccccc to C - ld a,b - rrca - rrca - rrca - and 11111b - ld b,a ;BC shr 3 to BC - ld hl,(alloca) ;base address of allocation vector - add hl,bc - ld a,(hl) ;byte to A, hl = .alloc(BC shr 3) - ;now move the bit to the low order position of A -rotl: rlca - dec e - jp nz,rotl - ret - - -set$alloc$bit: ;BC is the bit position of ALLOC to set or reset. The - ;value of the bit is in register E. - push de - call getallocbit ;shifted val A, count in D - and 11111110b ;mask low bit to zero (may be set) - pop bc - or c ;low bit of C is masked into A -; jp rotr ;to rotate back into proper position -; ret -rotr: - ;byte value from ALLOC is in register A, with shift count - ;in register C (to place bit back into position), and - ;target ALLOC position in registers HL, rotate and replace - rrca - dec d - jp nz,rotr ;back into position - ld (hl),a ;back to ALLOC - ret - -scandm: ;scan the disk map addressed by dptr for non-zero - ;entries, the allocation vector entry corresponding - ;to a non-zero entry is set to the value of C (0,1) - call getdptra ;HL = buffa + dptr - ;HL addresses the beginning of the directory entry - ld de,dskmap - add hl,de ;hl now addresses the disk map - push bc ;save the 0/1 bit to set - ld c,fcblen-dskmap+1;size of single byte disk map + 1 -scandm0: ;loop once for each disk map entry - pop de ;recall bit parity - dec c - ret z ;all done scanning? - ;no, get next entry for scan - push de ;replace bit parity - ld a,(single) - or a - jp z,scandm1 - ;single byte scan operation - push bc ;save counter - push hl ;save map address - ld c,(hl) - ld b,0 ;BC=block# - jp scandm2 - -scandm1: ;double byte scan operation - dec c ;count for double byte - push bc ;save counter - ld c,(hl) - inc hl - ld b,(hl) ;BC=block# - push hl ;save map address -scandm2: ;arrive here with BC=block#, E=0/1 - ld a,c - or b ;skip if = 0000 - jp z,scanm3 - ld hl,(maxall) ;check invalid index - ld a,l - sub c - ld a,h - sbc a,b ;maxall - block# - call nc,set$alloc$bit - ;bit set to 0/1 -scanm3: pop hl - inc hl ;to next bit position - pop bc ;recall counter - jp scandm0 ;for another item - -initialize: ;initialize the current disk - ;lret = false ;set to true if $ file exists - ;compute the length of the allocation vector - 2 - ld hl,(maxall) - ld c,3 ;perform maxall/8 - ;number of bytes in alloc vector is (maxall/8)+1 - call hlrotr - inc hl ;HL = maxall/8+1 - ld b,h - ld c,l ;count down BC til zero - ld hl,(alloca) ;base of allocation vector - ;fill the allocation vector with zeros -initial0: - ld (hl),0 - inc hl ;alloc(i)=0 - dec bc ;count length down - ld a,b - or c - jp nz,initial0 - ;set the reserved space for the directory - ld hl,(dirblk) - ex de,hl - ld hl,(alloca) ;HL=.alloc() - ld (hl),e - inc hl - ld (hl),d ;sets reserved directory blks - ;allocation vector initialized, home disk - call home - ;cdrmax = 3 (scans at least one directory record) - ld hl,(cdrmaxa) - ld (hl),3 - inc hl - ld (hl),0 - ;cdrmax = 0000 - call set$end$dir ;dcnt = enddir - ;read directory entries and check for allocated storage -initial2: - ld c,true - call read$dir - call end$of$dir - ret z ;return if end of directory - ;not end of directory, valid entry? - call getdptra ;HL = buffa + dptr - ld a,empty - cp (hl) - jp z,initial2 ;go get another item - ;not empty, user code the same? - ld a,(usrcode) - cp (hl) - jp nz,pdollar - ;same user code, check for '$' submit - inc hl - ld a,(hl) ;first character - sub '$' ;dollar file? - jp nz,pdollar - ;dollar file found, mark in lret - dec a - ld (lret),a ;lret = 255 -pdollar: ;now scan the disk map for allocated blocks - ld c,1 ;set to allocated - call scandm - call setcdr ;set cdrmax to dcnt - jp initial2 ;for another entry - -copy$dirloc: ;copy directory location to lret following - ;delete, rename, ... ops - ld a,(dirloc) - jp sta$ret -; ret - -compext: ;compare extent# in A with that in C, return nonzero - ;if they do not match - push bc ;save C's original value - push af - ld a,(extmsk) - cpl - ld b,a - ;B has negated form of extent mask - ld a,c - and b - ld c,a ;low bits removed from C - pop af - and b ;low bits removed from A - sub c - and maxext ;set flags - pop bc ;restore original values - ret - -search: ;search for directory element of length C at info - ld a,0ffh - ld (dirloc),a ;changed if actually found - ld hl,searchl - ld (hl),c ;searchl = C - ld hl,(info) - ld (searcha),hl ;searcha = info - call set$end$dir ;dcnt = enddir - call home ;to start at the beginning - ;(drop through to searchn) - -searchn: ;search for the next directory element, assuming - ;a previous call on search which sets searcha and - ;searchl - ld c,false - call read$dir ;read next dir element - call end$of$dir - jp z,search$fin ;skip to end if so - ;not end of directory, scan for match - ld hl,(searcha) - ex de,hl ;DE=beginning of user fcb - ld a,(de) ;first character - cp empty ;keep scanning if empty - jp z,searchnext - ;not empty, may be end of logical directory - push de ;save search address - call compcdr ;past logical end? - pop de ;recall address - jp nc,search$fin ;artificial stop -searchnext: - call getdptra ;HL = buffa+dptr - ld a,(searchl) - ld c,a ;length of search to c - ld b,0 ;b counts up, c counts down -searchloop: - ld a,c - or a - jp z,endsearch - ld a,(de) - cp '?' - jp z,searchok ;? matches all - ;scan next character if not ubytes - ld a,b - cp ubytes - jp z,searchok - ;not the ubytes field, extent field? - cp extnum ;may be extent field - ld a,(de) ;fcb character - jp z,searchext ;skip to search extent - sub (hl) - and 7fh ;mask-out flags/extent modulus - jp nz,searchn ;skip if not matched - jp searchok ;matched character - -searchext: ;A has fcb character - ;attempt an extent # match - push bc ;save counters - ld c,(hl) ;directory character to c - call compext ;compare user/dir char - pop bc ;recall counters - jp nz,searchn ;skip if no match -searchok: ;current character matches - inc de - inc hl - inc b - dec c - jp searchloop - -endsearch: ;entire name matches, return dir position - ld a,(dcnt) - and dskmsk - ld (lret),a - ;lret = low(dcnt) and 11b - ld hl,dirloc - ld a,(hl) - rla - ret nc ;dirloc=0ffh? - ;yes, change it to 0 to mark as found - xor a - ld (hl),a ;dirloc=0 - ret - -search$fin: ;end of directory, or empty name - call set$end$dir ;may be artifical end - ld a,255 - jp sta$ret - -delete: ;delete the currently addressed file - call check$write ;write protected? - ld c,extnum - call search ;search through file type -delete0: - ;loop while directory matches - call end$of$dir - ret z ;stop if end - ;set each non zero disk map entry to 0 - ;in the allocation vector - ;may be r/o file - call check$rodir ;ro disk error if found - call getdptra ;HL=.buff(dptr) - ld (hl),empty - ld c,0 - call scandm ;alloc elts set to 0 - call wrdir ;write the directory - call searchn ;to next element - jp delete0 ;for another record - -get$block: ;given allocation vector position BC, find the zero bit - ;closest to this position by searching left and right. - ;if found, set the bit to one and return the bit position - ;in hl. if not found (i.e., we pass 0 on the left, or - ;maxall on the right), return 0000 in hl - ld d,b - ld e,c ;copy of starting position to de -lefttst: - ld a,c - or b - jp z,righttst ;skip if left=0000 - ;left not at position zero, bit zero? - dec bc - push de - push bc ;left,right pushed - call getallocbit - rra - jp nc,retblock ;return block number if zero - ;bit is one, so try the right - pop bc - pop de ;left, right restored -righttst: - ld hl,(maxall) ;value of maximum allocation# - ld a,e - sub l - ld a,d - sbc a,h ;right=maxall? - jp nc,retblock0 ;return block 0000 if so - inc de - push bc - push de ;left, right pushed - ld b,d - ld c,e ;ready right for call - call getallocbit - rra - jp nc,retblock ;return block number if zero - pop de - pop bc ;restore left and right pointers - jp lefttst ;for another attempt -retblock: - rla - inc a ;bit back into position and set to 1 - ;d contains the number of shifts required to reposition - call rotr ;move bit back to position and store - pop hl - pop de ;HL returned value, DE discarded - ret - -retblock0: ;cannot find an available bit, return 0000 - ld a,c - or b - jp nz,lefttst ;also at beginning - ld hl,0000h - ret - -copy$fcb: ;copy the entire file control block - ld c,0 - ld e,fcblen ;start at 0, to fcblen-1 -; jp copy$dir - -copy$dir: ;copy fcb information starting at C for E bytes - ;into the currently addressed directory entry - push de ;save length for later - ld b,0 ;double index to BC - ld hl,(info) ;HL = source for data - add hl,bc - ex de,hl ;DE=.fcb(C), source for copy - call getdptra ;HL=.buff(dptr), destination - pop bc ;DE=source, HL=dest, C=length - call move ;data moved -seek$copy: ;enter from close to seek and copy current element - call seek$dir ;to the directory element - jp wrdir ;write the directory element -; ret -rename: ;rename the file described by the first half of - ;the currently addressed file control block. the - ;new name is contained in the last half of the - ;currently addressed file conrol block. the file - ;name and type are changed, but the reel number - ;is ignored. the user number is identical - call check$write ;may be write protected - ;search up to the extent field - ld c,extnum - call search - ;copy position 0 - ld hl,(info) - ld a,(hl) ;HL=.fcb(0), A=fcb(0) - ld de,dskmap - add hl,de ;HL=.fcb(dskmap) - ld (hl),a ;fcb(dskmap)=fcb(0) - ;assume the same disk drive for new named file -rename0: - call end$of$dir - ret z ;stop at end of dir - ;not end of directory, rename next element - call check$rodir ;may be read-only file - ld c,dskmap - ld e,extnum - call copy$dir - ;element renamed, move to next - call searchn - jp rename0 - -indicators: ;set file indicators for current fcb - ld c,extnum - call search ;through file type -indic0: call end$of$dir - ret z ;stop at end of dir - ;not end of directory, continue to change - ld c,0 - ld e,extnum ;copy name - call copy$dir - call searchn - jp indic0 - -open: ;search for the directory entry, copy to fcb - ld c,namlen - call search - call end$of$dir - ret z ;return with lret=255 if end - ;not end of directory, copy fcb information -open$copy: ;(referenced below to copy fcb info) - call getexta - ld a,(hl) - push af - push hl ;save extent# - call getdptra - ex de,hl ;DE = .buff(dptr) - ld hl,(info) ;HL=.fcb(0) - ld c,nxtrec ;length of move operation - push de ;save .buff(dptr) - call move ;from .buff(dptr) to .fcb(0) - ;note that entire fcb is copied, including indicators - call setfwf ;sets file write flag - pop de - ld hl,extnum - add hl,de ;HL=.buff(dptr+extnum) - ld c,(hl) ;C = directory extent number - ld hl,reccnt - add hl,de ;HL=.buff(dptr+reccnt) - ld b,(hl) ;B holds directory record count - pop hl - pop af - ld (hl),a ;restore extent number - ;HL = .user extent#, B = dir rec cnt, C = dir extent# - ;if user ext < dir ext then user := 128 records - ;if user ext = dir ext then user := dir records - ;if user ext > dir ext then user := 0 records - ld a,c - cp (hl) - ld a,b ;ready dir reccnt - jp z,open$rcnt ;if same, user gets dir reccnt - ld a,0 - jp c,open$rcnt ;user is larger - ld a,128 ;directory is larger -open$rcnt: ;A has record count to fill - ld hl,(info) - ld de,reccnt - add hl,de - ld (hl),a - ret - -mergezero: ;HL = .fcb1(i), DE = .fcb2(i), - ;if fcb1(i) = 0 then fcb1(i) := fcb2(i) - ld a,(hl) - inc hl - or (hl) - dec hl - ret nz ;return if = 0000 - ld a,(de) - ld (hl),a - inc de - inc hl ;low byte copied - ld a,(de) - ld (hl),a - dec de - dec hl ;back to input form - ret - -close: ;locate the directory element and re-write it - xor a - ld (lret),a - ld (dcnt),a - ld (dcnt+1),a - call nowrite - ret nz ;skip close if r/o disk - ;check file write flag - 0 indicates written - call getmodnum ;fcb(modnum) in A - and fwfmsk - ret nz ;return if bit remains set - ld c,namlen - call search ;locate file - call end$of$dir - ret z ;return if not found - ;merge the disk map at info with that at buff(dptr) - ld bc,dskmap - call getdptra - add hl,bc - ex de,hl ;DE is .buff(dptr+16) - ld hl,(info) - add hl,bc ;DE=.buff(dptr+16), HL=.fcb(16) - ld c,fcblen-dskmap;length of single byte dm -merge0: ld a,(single) - or a - jp z,merged ;skip to double - ;this is a single byte map - ;if fcb(i) = 0 then fcb(i) = buff(i) - ;if buff(i) = 0 then buff(i) = fcb(i) - ;if fcb(i) <> buff(i) then error - ld a,(hl) - or a - ld a,(de) - jp nz,fcbnzero - ;fcb(i) = 0 - ld (hl),a ;fcb(i) = buff(i) -fcbnzero: - or a - jp nz,buffnzero - ;buff(i) = 0 - ld a,(hl) - ld (de),a ;buff(i)=fcb(i) -buffnzero: - cp (hl) - jp nz,mergerr ;fcb(i) = buff(i)? - jp dmset ;if merge ok - -merged: ;this is a double byte merge operation - call mergezero ;buff = fcb if buff 0000 - ex de,hl - call mergezero - ex de,hl ;fcb = buff if fcb 0000 - ;they should be identical at this point - ld a,(de) - cp (hl) - jp nz,mergerr ;low same? - inc de - inc hl ;to high byte - ld a,(de) - cp (hl) - jp nz,mergerr ;high same? - ;merge operation ok for this pair - dec c ;extra count for double byte -dmset: inc de - inc hl ;to next byte position - dec c - jp nz,merge0 ;for more - ;end of disk map merge, check record count - ;DE = .buff(dptr)+32, HL = .fcb(32) - ld bc,-(fcblen-extnum) - add hl,bc - ex de,hl - add hl,bc - ;DE = .fcb(extnum), HL = .buff(dptr+extnum) - ld a,(de) ;current user extent number - ;if fcb(ext) >= buff(fcb) then - ;buff(ext) := fcb(ext), buff(rec) := fcb(rec) - cp (hl) - jp c,endmerge - ;fcb extent number >= dir extent number - ld (hl),a ;buff(ext) = fcb(ext) - ;update directory record count field - ld bc,reccnt-extnum - add hl,bc - ex de,hl - add hl,bc - ;DE=.buff(reccnt), HL=.fcb(reccnt) - ld a,(hl) - ld (de),a ;buff(reccnt)=fcb(reccnt) -endmerge: - ld a,true - ld (fcb$copied),a ;mark as copied - jp seek$copy ;ok to "wrdir" here - 1.4 compat - ; ret - -mergerr: ;elements did not merge correctly - ld hl,lret - dec (hl) ;=255 non zero flag set - ret - -make: ;create a new file by creating a directory entry - ;then opening the file - call check$write ;may be write protected - ld hl,(info) - push hl ;save fcb address, look for e5 - ld hl,efcb - ld (info),hl ;info = .empty - ld c,1 - call search ;length 1 match on empty entry - call end$of$dir ;zero flag set if no space - pop hl ;recall info address - ld (info),hl ;in case we return here - ret z ;return with error condition 255 if not found - ex de,hl ;DE = info address - ;clear the remainder of the fcb - ld hl,namlen - add hl,de ;HL=.fcb(namlen) - ld c,fcblen-namlen ;number of bytes to fill - xor a ;clear accumulator to 00 for fill -make0: ld (hl),a - inc hl - dec c - jp nz,make0 - ld hl,ubytes - add hl,de ;HL = .fcb(ubytes) - ld (hl),a ;fcb(ubytes) = 0 - call setcdr ;may have extended the directory - ;now copy entry to the directory - call copy$fcb - ;and set the file write flag to "1" - jp setfwf -; ret - -open$reel: ;close the current extent, and open the next one - ;if possible. RMF is true if in read mode - xor a - ld (fcb$copied),a ;set true if actually copied - call close ;close current extent - ;lret remains at enddir if we cannot open the next ext - call end$of$dir - ret z ;return if end - ;increment extent number - ld hl,(info) - ld bc,extnum - add hl,bc ;HL=.fcb(extnum) - ld a,(hl) - inc a - and maxext - ld (hl),a ;fcb(extnum)=++1 - jp z,open$mod ;move to next module if zero - ;may be in the same extent group - ld b,a - ld a,(extmsk) - and b - ;if result is zero, then not in the same group - ld hl,fcb$copied ;true if the fcb was copied to directory - and (hl) ;produces a 00 in accumulator if not written - jp z,open$reel0 ;go to next physical extent - ;result is non zero, so we must be in same logical ext - jp open$reel1 ;to copy fcb information -open$mod: ;extent number overflow, go to next module - ld bc,modnum-extnum - add hl,bc ;HL=.fcb(modnum) - inc (hl) ;fcb(modnum)=++1 - ;module number incremented, check for overflow - ld a,(hl) - and maxmod ;mask high order bits - jp z,open$r$err ;cannot overflow to zero - ;otherwise, ok to continue with new module -open$reel0: - ld c,namlen - call search ;next extent found? - call end$of$dir - jp nz,open$reel1 - ;end of file encountered - ld a,(rmf) - inc a ;0ffh becomes 00 if read - jp z,open$r$err ;sets lret = 1 - ;try to extend the current file - call make - ;cannot be end of directory - call end$of$dir - jp z,open$r$err ;with lret = 1 - jp open$reel2 - -open$reel1: ;not end of file, open - call open$copy -open$reel2: - call getfcb ;set parameters - xor a - jp sta$ret ;lret = 0 -; ret ;with lret = 0 - -open$r$err: ;cannot move to next extent of this file - call setlret1 ;lret = 1 - jp setfwf ;ensure that it will not be closed -; ret - -seqdiskread: ;sequential disk read operation - ld a,1 - ld (seqio),a - ;drop through to diskread - -diskread: ;(may enter from seqdiskread) - ld a,true - ld (rmf),a ;read mode flag = true (open$reel) - ;read the next record from the current fcb - call getfcb ;sets parameters for the read - ld a,(vrecord) - ld hl,rcount - cp (hl) ;vrecord-rcount - ;skip if rcount > vrecord - jp c,recordok - ;not enough records in the extent - ;record count must be 128 to continue - cp 128 ;vrecord = 128? - jp nz,diskeof ;skip if vrecord<>128 - call open$reel ;go to next extent if so - xor a - ld (vrecord),a ;vrecord=00 - ;now check for open ok - ld a,(lret) - or a - jp nz,diskeof ;stop at eof -recordok: ;arrive with fcb addressing a record to read - call index - ;error 2 if reading unwritten data - ;(returns 1 to be compatible with 1.4) - call allocated ;arecord=0000? - jp z,diskeof - ;record has been allocated, read it - call atran ;arecord now a disk address - call seek ;to proper track,sector - call rdbuff ;to dma address - jp setfcb ;replace parameter -; ret - -diskeof: - jp setlret1 ;lret = 1 -; ret - -seqdiskwrite: ;sequential disk write - ld a,1 - ld (seqio),a - ;drop through to diskwrite - -diskwrite: ;(may enter here from seqdiskwrite above) - ld a,false - ld (rmf),a ;read mode flag - ;write record to currently selected file - call check$write ;in case write protected - ld hl,(info) ;HL = .fcb(0) - call check$rofile ;may be a read-only file - call getfcb ;to set local parameters - ld a,(vrecord) - cp lstrec+1 ;vrecord-128 - ;skip if vrecord > lstrec - ;vrecord = 128, cannot open next extent - jp nc,setlret1 ;lret=1 -diskwr0: ;can write the next record, so continue - call index - call allocated - ld c,0 ;marked as normal write operation for wrbuff - jp nz,diskwr1 - ;not allocated - ;the argument to getblock is the starting - ;position for the disk search, and should be - ;the last allocated block for this file, or - ;the value 0 if no space has been allocated - call dm$position - ld (dminx),a ;save for later - ld bc,0000h ;may use block zero - or a - jp z,nopblock ;skip if no previous block - ;previous block exists at A - ld c,a - dec bc ;previous block # in BC - call getdm ;previous block # to HL - ld b,h - ld c,l ;BC=prev block# -nopblock: ;BC = 0000, or previous block # - call get$block ;block # to HL - ;arrive here with block# or zero - ld a,l - or h - jp nz,blockok - ;cannot find a block to allocate - ld a,2 - jp sta$ret ;lret=2 - -blockok: ;allocated block number is in HL - ld (arecord),hl - ex de,hl ;block number to DE - ld hl,(info) - ld bc,dskmap - add hl,bc ;HL=.fcb(dskmap) - ld a,(single) - or a ;set flags for single byte dm - ld a,(dminx) ;recall dm index - jp z,allocwd ;skip if allocating word - ;allocating a byte value - call addh - ld (hl),e ;single byte alloc - jp diskwru ;to continue - -allocwd: ;allocate a word value - ld c,a - ld b,0 ;double(dminx) - add hl,bc - add hl,bc ;HL=.fcb(dminx*2) - ld (hl),e - inc hl - ld (hl),d ;double wd -diskwru: ;disk write to previously unallocated block - ld c,2 ;marked as unallocated write -diskwr1: ;continue the write operation of no allocation error - ;C = 0 if normal write, 2 if to prev unalloc block - ld a,(lret) - or a - ret nz ;stop if non zero returned value - push bc ;save write flag - call atran ;arecord set - ld a,(seqio) - dec a - dec a - jp nz,diskwr11 - pop bc - push bc - ld a,c - dec a - dec a - jp nz,diskwr11 ;old allocation - push hl ;arecord in hl ret from atran - ld hl,(buffa) - ld d,a ;zero buffa & fill -fill0: ld (hl),a - inc hl - inc d - jp p,fill0 - call setdir - ld hl,(arecord1) - ld c,2 -fill1: ld (arecord),hl - push bc - call seek - pop bc - call wrbuff ;write fill record - ld hl,(arecord) ;restore last record - ld c,0 ;change allocate flag - ld a,(blkmsk) - ld b,a - and l - cp b - inc hl - jp nz,fill1 ;cont until cluster is zeroed - pop hl - ld (arecord),hl - call setdata -diskwr11: - call seek ;to proper file position - pop bc - push bc ;restore/save write flag (C=2 if new block) - call wrbuff ;written to disk - pop bc ;C = 2 if a new block was allocated, 0 if not - ;increment record count if rcount<=vrecord - ld a,(vrecord) - ld hl,rcount - cp (hl) ;vrecord-rcount - jp c,diskwr2 - ;rcount <= vrecord - ld (hl),a - inc (hl) ;rcount = vrecord+1 - ld c,2 ;mark as record count incremented -diskwr2: ;A has vrecord, C=2 if new block or new record# - dec c - dec c - jp nz,noupdate - push af ;save vrecord value - call getmodnum ;HL=.fcb(modnum), A=fcb(modnum) - ;reset the file write flag to mark as written fcb - and (not fwfmsk) and 0ffh;bit reset - ld (hl),a ;fcb(modnum) = fcb(modnum) and 7fh - pop af ;restore vrecord -noupdate: ;check for end of extent, if found attempt to open - ;next extent in preparation for next write - cp lstrec ;vrecord=lstrec? - jp nz,diskwr3 ;skip if not - ;may be random access write, if so we are done - ;change next - ld a,(seqio) - cp 1 - jp nz,diskwr3 ;skip next extent open op - ;update current fcb before going to next extent - call setfcb - call open$reel ;rmf=false - ;vrecord remains at lstrec causing eof if - ;no more directory space is available - ld hl,lret - ld a,(hl) - or a - jp nz,nospace - ;space available, set vrecord=255 - dec a - ld (vrecord),a ;goes to 00 next time -nospace: - ld (hl),0 ;lret = 00 for returned value -diskwr3: - jp setfcb ;replace parameters -; ret - -rseek: ;random access seek operation, C=0ffh if read mode - ;fcb is assumed to address an active file control block - ;(modnum has been set to 1100$0000b if previous bad seek) - xor a - ld (seqio),a ;marked as random access operation -rseek1: push bc ;save r/w flag - ld hl,(info) - ex de,hl ;DE will hold base of fcb - ld hl,ranrec - add hl,de ;HL=.fcb(ranrec) - ld a,(hl) - and 7fh - push af ;record number - ld a,(hl) - rla ;cy=lsb of extent# - inc hl - ld a,(hl) - rla - and 11111b ;A=ext# - ld c,a ;C holds extent number, record stacked - ld a,(hl) - rra - rra - rra - rra - and 1111b ;mod# - ld b,a ;B holds module#, C holds ext# - pop af ;recall sought record # - ;check to insure that high byte of ran rec = 00 - inc hl - ld l,(hl) ;l=high byte (must be 00) - inc l - dec l - ld l,6 ;zero flag, l=6 - ;produce error 6, seek past physical eod - jp nz,seekerr - ;otherwise, high byte = 0, A = sought record - ld hl,nxtrec - add hl,de ;HL = .fcb(nxtrec) - ld (hl),a ;sought rec# stored away - ;arrive here with B=mod#, C=ext#, DE=.fcb, rec stored - ;the r/w flag is still stacked. compare fcb values - ld hl,extnum - add hl,de - ld a,c ;A=seek ext# - sub (hl) - jp nz,ranclose ;tests for = extents - ;extents match, check mod# - ld hl,modnum - add hl,de - ld a,b ;B=seek mod# - ;could be overflow at eof, producing module# - ;of 90H or 10H, so compare all but fwf - sub (hl) - and 7fh - jp z,seekok ;same? -ranclose: - push bc - push de ;save seek mod#,ext#, .fcb - call close ;current extent closed - pop de - pop bc ;recall parameters and fill - ld l,3 ;cannot close error #3 - ld a,(lret) - inc a - jp z,badseek - ld hl,extnum - add hl,de - ld (hl),c ;fcb(extnum)=ext# - ld hl,modnum - add hl,de - ld (hl),b ;fcb(modnum)=mod# - call open ;is the file present? - ld a,(lret) - inc a - jp nz,seekok ;open successful? - ;cannot open the file, read mode? - pop bc ;r/w flag to c (=0ffh if read) - push bc ;everyone expects this item stacked - ld l,4 ;seek to unwritten extent #4 - inc c ;becomes 00 if read operation - jp z,badseek ;skip to error if read operation - ;write operation, make new extent - call make - ld l,5 ;cannot create new extent #5 - ld a,(lret) - inc a - jp z,badseek ;no dir space - ;file make operation successful -seekok: - pop bc ;discard r/w flag - xor a - jp sta$ret ;with zero set -badseek: ;fcb no longer contains a valid fcb, mark - ;with 1100$000b in modnum field so that it - ;appears as overflow with file write flag set - push hl ;save error flag - call getmodnum ;HL = .modnum - ld (hl),11000000b - pop hl ;and drop through -seekerr: - pop bc ;discard r/w flag - ld a,l - ld (lret),a ;lret=#, nonzero - ;setfwf returns non-zero accumulator for err - jp setfwf ;flag set, so subsequent close ok -; ret - -randiskread: ;random disk read operation - ld c,true ;marked as read operation - call rseek - call z,diskread ;if seek successful - ret - -randiskwrite: ;random disk write operation - ld c,false ;marked as write operation - call rseek - call z,diskwrite ;if seek successful - ret - -compute$rr: ;compute random record position for getfilesize/setrandom - ex de,hl - add hl,de - ;DE=.buf(dptr) or .fcb(0), HL = .f(nxtrec/reccnt) - ld c,(hl) - ld b,0 ;BC = 0000 0000 ?rrr rrrr - ld hl,extnum - add hl,de - ld a,(hl) - rrca - and 80h ;A=e000 0000 - add a,c - ld c,a - ld a,0 - adc a,b - ld b,a - ;BC = 0000 000? errrr rrrr - ld a,(hl) - rrca - and 0fh - add a,b - ld b,a - ;BC = 000? eeee errrr rrrr - ld hl,modnum - add hl,de - ld a,(hl) ;A=XXX? mmmm - add a,a - add a,a - add a,a - add a,a ;cy=? A=mmmm 0000 - push af - add a,b - ld b,a - ;cy=?, BC = mmmm eeee errr rrrr - push af ;possible second carry - pop hl ;cy = lsb of L - ld a,l ;cy = lsb of A - pop hl ;cy = lsb of L - or l ;cy/cy = lsb of A - and 1 ;A = 0000 000? possible carry-out - ret - -getfilesize: ;compute logical file size for current fcb - ld c,extnum - call search - ;zero the receiving ranrec field - ld hl,(info) - ld de,ranrec - add hl,de - push hl ;save position - ld (hl),d - inc hl - ld (hl),d - inc hl - ld (hl),d ;=00 00 00 -getsize: - call end$of$dir - jp z,setsize - ;current fcb addressed by dptr - call getdptra - ld de,reccnt ;ready for compute size - call compute$rr - ;A=0000 000? BC = mmmm eeee errr rrrr - ;compare with memory, larger? - pop hl - push hl ;recall, replace .fcb(ranrec) - ld e,a ;save cy - ld a,c - sub (hl) - inc hl ;ls byte - ld a,b - sbc a,(hl) - inc hl ;middle byte - ld a,e - sbc a,(hl) ;carry if .fcb(ranrec) > directory - jp c,getnextsize ;for another try - ;fcb is less or equal, fill from directory - ld (hl),e - dec hl - ld (hl),b - dec hl - ld (hl),c -getnextsize: - call searchn - jp getsize - -setsize: - pop hl ;discard .fcb(ranrec) - ret - -setrandom: ;set random record from the current file control block - ld hl,(info) - ld de,nxtrec ;ready params for computesize - call compute$rr ;DE=info, A=cy, BC=mmmm eeee errr rrrr - ld hl,ranrec - add hl,de ;HL = .fcb(ranrec) - ld (hl),c - inc hl - ld (hl),b - inc hl - ld (hl),a ;to ranrec - ret - -select: ;select disk info for subsequent input or output ops - ld hl,(dlog) - ld a,(curdsk) - ld c,a - call hlrotr - push hl - ex de,hl ;save it for test below, send to seldsk - call selectdisk - pop hl ;recall dlog vector - call z,sel$error ;returns true if select ok - ;is the disk logged in? - ld a,l - rra - ret c ;return if bit is set - ;disk not logged in, set bit and initialize - ld hl,(dlog) - ld c,l - ld b,h ;call ready - call set$cdisk - ld (dlog),hl ;dlog=set$cdisk(dlog) - jp initialize -; ret - -curselect: - ld a,(linfo) - ld hl,curdsk - cp (hl) - ret z ;skip if linfo=curdsk - ld (hl),a ;curdsk=info - jp select -; ret - -reselect: ;check current fcb to see if reselection necessary - ld a,true - ld (resel),a ;mark possible reselect - ld hl,(info) - ld a,(hl) ;drive select code - and 11111b ;non zero is auto drive select - dec a ;drive code normalized to 0..30, or 255 - ld (linfo),a ;save drive code - cp 30 - jp nc,noselect - ;auto select function, save curdsk - ld a,(curdsk) - ld (olddsk),a ;olddsk=curdsk - ld a,(hl) - ld (fcbdsk),a ;save drive code - and 11100000b - ld (hl),a ;preserve hi bits - call curselect -noselect: ;set user code - ld a,(usrcode) ;0...31 - ld hl,(info) - or (hl) - ld (hl),a - ret - -; individual function handlers -func12: ;return version number - ld a,dvers - jp sta$ret ;lret = dvers (high = 00) -; ret -; jp goback - -func13: ;reset disk system - initialize to disk 0 - ld hl,0 - ld (rodsk),hl - ld (dlog),hl - xor a - ld (curdsk),a ;note that usrcode remains unchanged - ld hl,tbuff - ld (dmaad),hl ;dmaad = tbuff - call setdata ;to data dma address - jp select -; ret -; jp goback - -func14 equ curselect ;select disk info -; ret -; jp goback - -func15: ;open file - call clrmodnum ;clear the module number - call reselect - jp open -; ret -; jp goback - -func16: ;close file - call reselect - jp close -; ret -; jp goback - -func17: ;search for first occurrence of a file - ld c,0 ;length assuming '?' true - ex de,hl ;was lhld info - ld a,(hl) - cp '?' ;no reselect if ? - jp z,qselect ;skip reselect if so - ;normal search - call getexta - ld a,(hl) - cp '?' ; - call nz,clrmodnum ;module number zeroed - call reselect - ld c,namlen -qselect: - call search - jp dir$to$user ;copy directory entry to user -; ret -; jp goback - -func18: ;search for next occurrence of a file name - ld hl,(searcha) - ld (info),hl - call reselect - call searchn - jp dir$to$user ;copy directory entry to user -; ret -; jp goback - -func19: ;delete a file - call reselect - call delete - jp copy$dirloc -; ret -; jp goback - -func20: ;read a file - call reselect - jp seqdiskread -; jp goback - -func21: ;write a file - call reselect - jp seqdiskwrite -; jp goback - -func22: ;make a file - call clrmodnum - call reselect - jp make -; ret -; jp goback - -func23: ;rename a file - call reselect - call rename - jp copy$dirloc -; ret -; jp goback - -func24: ;return the login vector - ld hl,(dlog) - jp sthl$ret -; ret -; jp goback - -func25: ;return selected disk number - ld a,(curdsk) - jp sta$ret -; ret -; jp goback - -func26: ;set the subsequent dma address to info - ex de,hl ;was lhld info - ld (dmaad),hl ;dmaad = info - jp setdata ;to data dma address -; ret -; jp goback - -func27: ;return the login vector address - ld hl,(alloca) - jp sthl$ret -; ret -; jp goback - -func28 equ set$ro - ;write protect current disk -; ret -; jp goback - -func29: ;return r/o bit vector - ld hl,(rodsk) - jp sthl$ret -; ret -; jp goback - -func30: ;set file indicators - call reselect - call indicators - jp copy$dirloc ;lret=dirloc -; ret -; jp goback - -func31: ;return address of disk parameter block - ld hl,(dpbaddr) -sthl$ret: - ld (aret),hl - ret -; jp goback - -func32: ;set user code - ld a,(linfo) - cp 0ffh - jp nz,setusrcode - ;interrogate user code instead - ld a,(usrcode) - jp sta$ret ;lret=usrcode -; ret -; jp goback - -setusrcode: - and 1fh - ld (usrcode),a - ret -; jp goback - -func33: ;random disk read operation - call reselect - jp randiskread ;to perform the disk read -; ret -; jp goback - -func34: ;random disk write operation - call reselect - jp randiskwrite ;to perform the disk write -; ret -; jp goback - -func35: ;return file size (0-65536) - call reselect - jp getfilesize -; ret -; jp goback - -func36 equ setrandom ;set random record -; ret -; jp goback - -func37: ld hl,(info) - ld a,l - cpl - ld e,a - ld a,h - cpl - ld hl,(dlog) - and h - ld d,a - ld a,l - and e - ld e,a - ld hl,(rodsk) - ex de,hl - ld (dlog),hl - ld a,l - and e - ld l,a - ld a,h - and d - ld h,a - ld (rodsk),hl - ret - -goback: ;arrive here at end of processing to return to user - ld a,(resel) - or a - jp z,retmon - ;reselection may have taken place - ld hl,(info) - ld (hl),0 ;fcb(0)=0 - ld a,(fcbdsk) - or a - jp z,retmon - ;restore disk number - ld (hl),a ;fcb(0)=fcbdsk - ld a,(olddsk) - ld (linfo),a - call curselect - -; return from the disk monitor -retmon: ld hl,(entsp) - ld sp,hl ;user stack restored - ld hl,(aret) - ld a,l - ld b,h ;BA = HL = aret - ret - -func38 equ func$ret -func39 equ func$ret -func40: ;random disk write with zero fill of unallocated block - call reselect - ld a,2 - ld (seqio),a - ld c,false - call rseek1 - call z,diskwrite ;if seek successful - ret - -; data areas - -; initialized data -efcb: db empty ;0e5=available dir entry -rodsk: dw 0 ;read only disk vector -dlog: dw 0 ;logged-in disks -dmaad: dw tbuff ;initial dma address - -; curtrka - alloca are set upon disk select -; (data must be adjacent, do not insert variables) -; (address of translate vector, not used) -cdrmaxa: - ds word ;pointer to cur dir max value -curtrka: - ds word ;current track address -curreca: - ds word ;current record address -buffa: ds word ;pointer to directory dma address -dpbaddr: - ds word ;current disk parameter block address -checka: ds word ;current checksum vector address -alloca: ds word ;current allocation vector address -addlist equ $-buffa ;address list size - -; sectpt - offset obtained from disk parm block at dpbaddr -; (data must be adjacent, do not insert variables) -sectpt: ds word ;sectors per track -blkshf: ds byte ;block shift factor -blkmsk: ds byte ;block mask -extmsk: ds byte ;extent mask -maxall: ds word ;maximum allocation number -dirmax: ds word ;largest directory number -dirblk: ds word ;reserved allocation bits for directory -chksiz: ds word ;size of checksum vector -offset: ds word ;offset tracks at beginning -dpblist equ $-sectpt ;size of area - -; local variables -tranv: ds word ;address of translate vector -fcb$copied: - ds byte ;set true if copy$fcb called -rmf: ds byte ;read mode flag for open$reel -dirloc: ds byte ;directory flag in rename, etc. -seqio: ds byte ;1 if sequential i/o -linfo: ds byte ;low(info) -dminx: ds byte ;local for diskwrite -searchl: - ds byte ;search length -searcha: - ds word ;search address -tinfo: ds word ;temp for info in "make" -single: ds byte ;set true if single byte allocation map -resel: ds byte ;reselection flag -olddsk: ds byte ;disk on entry to bdos -fcbdsk: ds byte ;disk named in fcb -rcount: ds byte ;record count in current fcb -extval: ds byte ;extent number and extmsk -vrecord: - ds word ;current virtual record -arecord: - ds word ;current actual record -arecord1: - ds word ;current actual block# * blkmsk - -; local variables for directory access -dptr: ds byte ;directory pointer 0,1,2,3 -dcnt: ds word ;directory counter 0,1,...,dirmax -drec: ds word ;directory record 0,1,...,dirmax/4 - -;bios equ ($ and 0ff00h)+100h;next module - - end diff --git a/doug/src/dribdos.s b/doug/src/dribdos.s deleted file mode 100755 index 1cb3a8f2..00000000 --- a/doug/src/dribdos.s +++ /dev/null @@ -1,2838 +0,0 @@ -;-------------------------------------------------------- -; File Created by SDCC : free open source ANSI-C Compiler -; Version 3.0.2 #6489 (May 10 2011) (Mac OS X x86_64) -; This file was generated Sun May 29 01:02:12 2011 -;-------------------------------------------------------- - .module dribdos - .optsdcc -mz80 - -;-------------------------------------------------------- -; Public variables in this module -;-------------------------------------------------------- - .globl _bdos -;-------------------------------------------------------- -; special function registers -;-------------------------------------------------------- -;-------------------------------------------------------- -; ram data -;-------------------------------------------------------- - .area _DATA -;-------------------------------------------------------- -; overlayable items in ram -;-------------------------------------------------------- - .area _OVERLAY -;-------------------------------------------------------- -; external initialized ram data -;-------------------------------------------------------- -;-------------------------------------------------------- -; global & static initialisations -;-------------------------------------------------------- - .area _HOME - .area _GSINIT - .area _GSFINAL - .area _GSINIT -;-------------------------------------------------------- -; Home -;-------------------------------------------------------- - .area _HOME - .area _HOME -;-------------------------------------------------------- -; code -;-------------------------------------------------------- - .area _BDOS -;dribdos.c:4: void bdos(int argc,char **argv) -; --------------------------------- -; Function bdos -; --------------------------------- -_bdos_start:: -_bdos: -;; push ix -;; ld ix,#0 -;; add ix,sp -;; ;dribdos.c:7: } -;; pop ix -;; ret - -;; dwg ; begin DRI source code here - - .title 'Bdos Interface, Bdos, Version 2.2 Feb, 1980' - -;;dwg;;: .Z80 -;; aseg - org 100h - maclib MEMCFG.LIB ; define configuration parameters - .phase bdosph -bios equ biosph - -;***************************************************************** -;***************************************************************** -;** ** -;** B a s i c D i s k O p e r a t i n g S y s t e m ** -;** I n t e r f a c e M o d u l e ** -;** ** -;***************************************************************** -;***************************************************************** - -; Copyright (c) 1978, 1979, 1980 -; Digital Research -; Box 579, Pacific Grove -; California - - -; 20 january 1980 - -ssize equ 24 ;24 level stack - -; low memory locations -reboot equ 0000h ;reboot system -ioloc equ 0003h ;i/o byte location -bdosa equ 0006h ;address field of jp BDOS - -; bios access constants -bootf defl bios+3*0 ;cold boot function -wbootf defl bios+3*1 ;warm boot function -constf defl bios+3*2 ;console status function -coninf defl bios+3*3 ;console input function -conoutf defl bios+3*4 ;console output function -listf defl bios+3*5 ;list output function -punchf defl bios+3*6 ;punch output function -readerf defl bios+3*7 ;reader input function -homef defl bios+3*8 ;disk home function -seldskf defl bios+3*9 ;select disk function -settrkf defl bios+3*10 ;set track function -setsecf defl bios+3*11 ;set sector function -setdmaf defl bios+3*12 ;set dma function -readf defl bios+3*13 ;read disk function -writef defl bios+3*14 ;write disk function -liststf defl bios+3*15 ;list status function -sectran defl bios+3*16 ;sector translate - -; equates for non graphic characters -ctlc equ 03h ;control c -ctle equ 05h ;physical eol -ctlh equ 08h ;backspace -ctlp equ 10h ;prnt toggle -ctlr equ 12h ;repeat line -ctls equ 13h ;stop/start screen -ctlu equ 15h ;line delete -ctlx equ 18h ;=ctl-u -ctlz equ 1ah ;end of file -rubout equ 7fh ;char delete -tab equ 09h ;tab char -cr equ 0dh ;carriage return -lf equ 0ah ;line feed -ctl equ 5eh ;up arrow - - .db 0,0,0,0,0,0 - -; enter here from the user's program with function number in c, -; and information address in d,e - jp bdose ;past parameter block - -; ************************************************ -; *** relative locations 0009 - 000e *** -; ************************************************ -pererr: .dw persub ;permanent error subroutine -selerr: .dw selsub ;select error subroutine -roderr: .dw rodsub ;ro disk error subroutine -roferr: .dw rofsub ;ro file error subroutine - - -bdose: ex de,hl ;arrive here from user programs - ld (info),hl - ex de,hl ;info=DE, DE=info - ld a,e - ld (linfo),a ;linfo = low(info) - don't equ - ld hl,0 - ld (aret),hl ;return value defaults to 0000 - ;save user's stack pointer, set to local stack - add hl,sp - ld (entsp),hl ;entsp = stackptr - ld sp,lstack ;local stack setup - xor a - ld (fcbdsk),a - ld (resel),a ;fcbdsk,resel=false - ld hl,goback ;return here after all functions - push hl ;jmp goback equivalent to ret - ld a,c - cp nfuncs - ret nc ;skip if invalid # - ld c,e ;possible output character to C - ld hl,functab - ld e,a - ld d,0 ;DE=func, HL=.ciotab - add hl,de - add hl,de - ld e,(hl) - inc hl - ld d,(hl) ;DE=functab(func) - ld hl,(info) ;info in DE for later xchg - ex de,hl - jp (hl) ;dispatched - -; dispatch table for functions -functab: - dw wbootf, func1, func2, func3 - dw punchf, listf, func6, func7 - dw func8, func9, func10,func11 -diskf equ ($-functab)/2 ;disk funcs - dw func12,func13,func14,func15 - dw func16,func17,func18,func19 - dw func20,func21,func22,func23 - dw func24,func25,func26,func27 - dw func28,func29,func30,func31 - dw func32,func33,func34,func35 - dw func36,func37,func38,func39 - dw func40 -nfuncs equ ($-functab)/2 - - -; error subroutines -persub: ld hl,permsg ;report permanent error - call errflg ;to report the error - cp ctlc - jp z,reboot ;reboot if response is ctlc - ret ;and ignore the error - -selsub: ld hl,selmsg ;report select error - jp wait$err ;wait console before boot - -rodsub: ld hl,rodmsg ;report write to read/only disk - jp wait$err ;wait console - -rofsub: ;report read/only file - ld hl,rofmsg ;drop through to wait for console - -wait$err: ;wait for response before boot - call errflg - jp reboot - -; error messages -dskmsg: db 'Bdos Err On ' -dskerr: db ' : $' ;filled in by errflg -permsg: db 'Bad Sector$' -selmsg: db 'Select$' -rofmsg: db 'File ' -rodmsg: db 'R/O$' - - -errflg: push hl ;report error to console, message address in HL - call crlf ;stack mssg address, new line - ld a,(curdsk) - add a,'A' - ld (dskerr),a ;current disk name - ld bc,dskmsg - call print ;the error message - pop bc - call print ;error mssage tail -; jp conin ;to get the input character - ;(drop through to conin) -; ret - - -; console handlers -conin: ld hl,kbchar ;read console character to A - ld a,(hl) - ld (hl),0 - or a - ret nz - ;no previous keyboard character ready - jp coninf ;get character externally -; ret -conech: call conin ;read character with echo - call echoc - ret c ;echo character? - ;character must be echoed before return - push af - ld c,a - call tabout - pop af - ret ;with character in A - -echoc: ;echo character if graphic - cp cr ;cr, lf, tab, or backspace - ret z ;carriage return? - cp lf - ret z ;line feed? - cp tab - ret z ;tab? - cp ctlh - ret z ;backspace? - cp ' ' - ret ;carry set if not graphic - -conbrk: ;check for character ready - ld a,(kbchar) - or a - jp nz,conb1 ;skip if active kbchar - ;no active kbchar, check external break - call constf - and 1 - ret z ;return if no char ready - ;character ready, read it - call coninf ;to A - cp ctls - jp nz,conb0 ;check stop screen function - ;found ctls, read next character - call coninf ;to A - cp ctlc - jp z,reboot ;ctlc implies re-boot - ;not a reboot, act as if nothing has happened - xor a - ret ;with zero in accumulator -conb0: - ;character in accum, save it - ld (kbchar),a -conb1: - ;return with true set in accumulator - ld a,1 - ret - -conout: ;compute character position/write console char from C - ;compcol = true if computing column position - ld a,(compcol) - or a - jp nz,compout - ;write the character, then compute the column - ;write console character from C - push bc - call conbrk ;check for screen stop function - pop bc - push bc ;recall/save character - call conoutf ;externally, to console - pop bc - push bc ;recall/save character - ;may be copying to the list device - ld a,(listcp) - or a - call nz,listf ;to printer, if so - pop bc ;recall the character -compout: - ld a,c ;recall the character - ;and compute column position - ld hl,column ;A = char, HL = .column - cp rubout - ret z ;no column change if nulls - inc (hl) ;column = column + 1 - cp ' ' - ret nc ;return if graphic - ;not graphic, reset column position - dec (hl) ;column = column - 1 - ld a,(hl) - or a - ret z ;return if at zero - ;not at zero, may be backspace or end line - ld a,c ;character back to A - cp ctlh - jp nz,notbacksp - ;backspace character - dec (hl) ;column = column - 1 - ret - -notbacksp: ;not a backspace character, eol? - cp lf - ret nz ;return if not - ;end of line, column = 0 - ld (hl),0 ;column = 0 - ret - -ctlout: ;send C character with possible preceding up-arrow - ld a,c - call echoc ;cy if not graphic (or special case) - jp nc,tabout ;skip if graphic, tab, cr, lf, or ctlh - ;send preceding up arrow - push af - ld c,ctl - call conout ;up arrow - pop af - or 40h ;becomes graphic letter - ld c,a ;ready to print - ;(drop through to tabout) - -tabout: ;expand tabs to console - ld a,c - cp tab - jp nz,conout ;direct to conout if not - ;tab encountered, move to next tab position -tab0: ld c,' ' - call conout ;another blank - ld a,(column) - and 111b ;column mod 8 = 0 ? - jp nz,tab0 ;back for another if not - ret - -backup: ;back-up one screen position - call pctlh - ld c,' ' - call conoutf -; (drop through to pctlh) -pctlh: ;send ctlh to console without affecting column count - ld c,ctlh - jp conoutf -; ret -crlfp: ;print #, cr, lf for ctlx, ctlu, ctlr functions - ;then move to strtcol (starting column) - ld c,'#' - call conout - call crlf ;column = 0, move to position strtcol -crlfp0: ld a,(column) - ld hl,strtcol - cp (hl) - ret nc ;stop when column reaches strtcol - ld c,' ' - call conout ;print blank - jp crlfp0 - -crlf: ld c,cr ;carriage return line feed sequence - call conout - ld c,lf - jp conout -; ret -print: ld a,(bc) ;print message until M(BC) = '$' - cp '$' - ret z ;stop on $ - ;more to print - inc bc - push bc - ld c,a ;char to C - call tabout ;another character printed - pop bc - jp print - -read: ;read to info address (max length, current length, buffer) - ld a,(column) - ld (strtcol),a ;save start for ctl-x, ctl-h - ld hl,(info) - ld c,(hl) - inc hl - push hl - ld b,0 - ;B = current buffer length, - ;C = maximum buffer length, - ;HL= next to fill - 1 -readnx: ;read next character, BC, HL active - push bc - push hl ;blen, cmax, HL saved -readn0: call conin ;next char in A - and 7fh ;mask parity bit - pop hl - pop bc ;reactivate counters - cp cr - jp z,readen ;end of line? - cp lf - jp z,readen ;also end of line - cp ctlh - jp nz,noth ;backspace? - ;do we have any characters to back over? - ld a,b - or a - jp z,readnx - ;characters remain in buffer, backup one - dec b ;remove one character - ld a,(column) - ld (compcol),a ;col > 0 - ;compcol > 0 marks repeat as length compute - jp linelen ;uses same code as repeat - -noth: ;not a backspace - cp rubout - jp nz,notrub ;rubout char? - ;rubout encountered, rubout if possible - ld a,b - or a - jp z,readnx ;skip if len=0 - ;buffer has characters, resend last char - ld a,(hl) - dec b - dec hl ;A = last char - ;blen=blen-1, next to fill - 1 decremented - jp rdech1 ;act like this is an echo - -notrub: ;not a rubout character, check end line - cp ctle - jp nz,note ;physical end line? - ;yes, save active counters and force eol - push bc - push hl - call crlf - xor a - ld (strtcol),a ;start position = 00 - jp readn0 ;for another character - -note: ;not end of line, list toggle? - cp ctlp - jp nz,notp ;skip if not ctlp - ;list toggle - change parity - push hl ;save next to fill - 1 - ld hl,listcp ;HL=.listcp flag - ld a,1 - sub (hl) ;True-listcp - ld (hl),a ;listcp = not listcp - pop hl - jp readnx ;for another char - -notp: ;not a ctlp, line delete? - cp ctlx - jp nz,notx - pop hl ;discard start position - ;loop while column > strtcol -backx: ld a,(strtcol) - ld hl,column - cp (hl) - jp nc,read ;start again - dec (hl) ;column = column - 1 - call backup ;one position - jp backx - -notx: ;not a control x, control u? - ;not control-X, control-U? - cp ctlu - jp nz,notu ;skip if not - ;delete line (ctlu) - call crlfp ;physical eol - pop hl ;discard starting position - jp read ;to start all over - -notu: ;not line delete, repeat line? - cp ctlr - jp nz,notr -linelen: ;repeat line, or compute line len (ctlh) - ;if compcol > 0 - push bc - call crlfp ;save line length - pop bc - pop hl - push hl - push bc - ;bcur, cmax active, beginning buff at HL -rep0: ld a,b - or a - jp z,rep1 ;count len to 00 - inc hl - ld c,(hl) ;next to print - dec b - push bc - push hl ;count length down - call ctlout ;character echoed - pop hl - pop bc ;recall remaining count - jp rep0 ;for the next character - -rep1: ;end of repeat, recall lengths - ;original BC still remains pushed - push hl ;save next to fill - ld a,(compcol) - or a ;>0 if computing length - jp z,readn0 ;for another char if so - ;column position computed for ctlh - ld hl,column - sub (hl) ;diff > 0 - ld (compcol),a ;count down below - ;move back compcol-column spaces -backsp: ;move back one more space - call backup ;one space - ld hl,compcol - dec (hl) - jp nz,backsp - jp readn0 ;for next character - -notr: ;not a ctlr, place into buffer -rdecho: inc hl - ld (hl),a ;character filled to mem - inc b ;blen = blen + 1 -rdech1: ;look for a random control character - push bc - push hl ;active values saved - ld c,a ;ready to print - call ctlout ;may be up-arrow C - pop hl - pop bc - ld a,(hl) ;recall char - cp ctlc ;set flags for reboot test - ld a,b ;move length to A - jp nz,notc ;skip if not a control c - cp 1 ;control C, must be length 1 - jp z,reboot ;reboot if blen = 1 - ;length not one, so skip reboot -notc: ;not reboot, are we at end of buffer? - cp c - jp c,readnx ;go for another if not -readen: ;end of read operation, store blen - pop hl - ld (hl),b ;M(current len) = B - ld c,cr - jp conout ;return carriage -; ret -func1: ;return console character with echo - call conech - jp sta$ret - -func2 equ tabout - ;write console character with tab expansion - -func3: ;return reader character - call readerf - jp sta$ret - -;func4: equated to punchf - ;write punch character - -;func5: equated to listf - ;write list character - ;write to list device - -func6: ;direct console i/o - read if 0ffh - ld a,c - inc a - jp z,dirinp ;0ffh => 00h, means input mode - inc a - jp z,constf ;0feH in C for status - ;direct output function - jp conoutf - -dirinp: call constf ;status check - or a - jp z,retmon ;skip, return 00 if not ready - ;character is ready, get it - call coninf ;to A - jp sta$ret - -func7: ;return io byte - ld a,(ioloc) - jp sta$ret - -func8: ;set i/o byte - ld hl,ioloc - ld (hl),c - ret ;jmp goback - -func9: ;write line until $ encountered - ex de,hl ;was lhld info - ld c,l - ld b,h ;BC=string address - jp print ;out to console - -func10 equ read - ;read a buffered console line - -func11: ;check console status - call conbrk - ;(drop through to sta$ret) -sta$ret: ;store the A register to aret - ld (aret),a -func$ret: - ret ;jmp goback (pop stack for non cp/m functions) - -setlret1: ;set lret = 1 - ld a,1 - jp sta$ret - - - -; data areas - -compcol: - db 0 ;true if computing column position -strtcol: - db 0 ;starting column position after read -column: db 0 ;column position -listcp: db 0 ;listing toggle -kbchar: db 0 ;initial key char = 00 -entsp: ds 2 ;entry stack pointer - ds ssize*2 ;stack size -lstack: -; end of Basic I/O System - -;***************************************************************** -;***************************************************************** - -; common values shared between bdosi and bdos -usrcode: - db 0 ;current user number -curdsk: db 0 ;current disk number -info: ds 2 ;information address -aret: ds 2 ;address value to return -lret equ aret ;low(aret) - -;***************************************************************** -;***************************************************************** -;** ** -;** B a s i c D i s k O p e r a t i n g S y s t e m ** -;** ** -;***************************************************************** -;***************************************************************** - -dvers equ 22h ;version 2.2 -; module addresses - -; literal constants -true equ 0ffh ;constant true -false equ 000h ;constant false -enddir equ 0ffffh ;end of directory -byte equ 1 ;number of bytes for "byte" type -word equ 2 ;number of bytes for "word" type - -; fixed addresses in low memory -tfcb equ 005ch ;default fcb location -tbuff equ 0080h ;default buffer location - -; fixed addresses referenced in bios module are -; pererr (0009), selerr (000c), roderr (000f) - -; error message handlers - -;per$error: ;report permanent error to user -; ld hl,pererr -; jp goerr - -;rod$error: ;report read/only disk error -; ld hl,roderr -; jp goerr - -;rof$error: ;report read/only file error -; ld hl,roferr -; jp goerr - -sel$error: ;report select error - ld hl,selerr - - -goerr: ;HL = .errorhandler, call subroutine - ld e,(hl) - inc hl - ld d,(hl) ;address of routine in DE - ex de,hl - jp (hl) ;to subroutine - - - -; local subroutines for bios interface - -move: ;move data length of length C from source DE to - ;destination given by HL - inc c ;in case it is zero -move0: dec c - ret z ;more to move - ld a,(de) - ld (hl),a ;one byte moved - inc de - inc hl ;to next byte - jp move0 - -selectdisk: ;select the disk drive given by curdsk, and fill - ;the base addresses curtrka - alloca, then fill - ;the values of the disk parameter block - ld a,(curdsk) - ld c,a ;current disk# to c - ;lsb of e = 0 if not yet logged - in - call seldskf ;HL filled by call - ;HL = 0000 if error, otherwise disk headers - ld a,h - or l - ret z ;return with 0000 in HL and z flag - ;disk header block address in hl - ld e,(hl) - inc hl - ld d,(hl) - inc hl ;DE=.tran - ld (cdrmaxa),hl - inc hl - inc hl ;.cdrmax - ld (curtrka),hl - inc hl - inc hl ;HL=.currec - ld (curreca),hl - inc hl - inc hl ;HL=.buffa - ;DE still contains .tran - ex de,hl - ld (tranv),hl ;.tran vector - ld hl,buffa ;DE= source for move, HL=dest - ld c,addlist - call move ;addlist filled - ;now fill the disk parameter block - ld hl,(dpbaddr) - ex de,hl ;DE is source - ld hl,sectpt ;HL is destination - ld c,dpblist - call move ;data filled - ;now set single/double map mode - ld hl,(maxall) ;largest allocation number - ld a,h ;00 indicates < 255 - ld hl,single - ld (hl),true ;assume a=00 - or a - jp z,retselect - ;high order of maxall not zero, use double dm - ld (hl),false -retselect: - ld a,true - or a - ret ;select disk function ok - -home: ;move to home position, then offset to start of dir - call homef ;move to track 00, sector 00 reference - ;lxi h,offset ;mov c,m ;inx h ;mov b,m ;call settrkf - ;first directory position selected - xor a ;constant zero to accumulator - ld hl,(curtrka) - ld (hl),a - inc hl - ld (hl),a ;curtrk=0000 - ld hl,(curreca) - ld (hl),a - inc hl - ld (hl),a ;currec=0000 - ;curtrk, currec both set to 0000 - ret - -rdbuff: ;read buffer and check condition - call readf ;current drive, track, sector, dma - jp diocomp ;check for i/o errors - -wrbuff: ;write buffer and check condition - ;write type (wrtype) is in register C - ;wrtype = 0 => normal write operation - ;wrtype = 1 => directory write operation - ;wrtype = 2 => start of new block - call writef ;current drive, track, sector, dma -diocomp: ;check for disk errors - or a - ret z - ld hl,pererr - jp goerr - -seek$dir: ;seek the record containing the current dir entry - ld hl,(dcnt) ;directory counter to HL - ld c,dskshf - call hlrotr ;value to HL - ld (arecord),hl - ld (drec),hl ;ready for seek -; jp seek -; ret - - -seek: ;seek the track given by arecord (actual record) - ;local equates for registers - ;load the registers from memory - ld hl,arecord - ld c,(hl) - inc hl - ld b,(hl) - ld hl,(curreca) - ld e,(hl) - inc hl - ld d,(hl) - ld hl,(curtrka) - ld a,(hl) - inc hl - ld h,(hl) - ld l,a - ;loop while arecord < currec -seek0: ld a,c - sub e - ld a,b - sbc a,d - jp nc,seek1 ;skip if arecord >= currec - ;currec = currec - sectpt - push hl - ld hl,(sectpt) - ld a,e - sub l - ld e,a - ld a,d - sbc a,h - ld d,a - pop hl - ;curtrk = curtrk - 1 - dec hl - jp seek0 ;for another try - -seek1: ;look while arecord >= (t:=currec + sectpt) - push hl - ld hl,(sectpt) - add hl,de ;HL = currec+sectpt - jp c,seek2 ;can be > FFFFH - ld a,c - sub l - ld a,b - sbc a,h - jp c,seek2 ;skip if t > arecord - ;currec = t - ex de,hl - ;curtrk = curtrk + 1 - pop hl - inc hl - jp seek1 ;for another try - -seek2: pop hl - ;arrive here with updated values in each register - push bc - push de - push hl ;to stack for later - ;stack contains (lowest) BC=arecord, DE=currec, HL=curtrk - ex de,hl - ld hl,(offset) - add hl,de ;HL = curtrk+offset - ld b,h - ld c,l - call settrkf ;track set up - ;note that BC - curtrk is difference to move in bios - pop de ;recall curtrk - ld hl,(curtrka) - ld (hl),e - inc hl - ld (hl),d ;curtrk updated - ;now compute sector as arecord-currec - pop de ;recall currec - ld hl,(curreca) - ld (hl),e - inc hl - ld (hl),d - pop bc ;BC=arecord, DE=currec - ld a,c - sub e - ld c,a - ld a,b - sbc a,d - ld b,a - ld hl,(tranv) - ex de,hl ;BC=sector#, DE=.tran - call sectran ;HL = tran(sector) - ld c,l - ld b,h ;BC = tran(sector) - jp setsecf ;sector selected -; ret - -; file control block (fcb) constants -empty equ 0e5h ;empty directory entry -lstrec equ 127 ;last record# in extent -recsiz equ 128 ;record size -fcblen equ 32 ;file control block size -dirrec equ recsiz/fcblen ;directory elts / record -dskshf equ 2 ;log2(dirrec) -dskmsk equ dirrec-1 -fcbshf equ 5 ;log2(fcblen) - -extnum equ 12 ;extent number field -maxext equ 31 ;largest extent number -ubytes equ 13 ;unfilled bytes field -modnum equ 14 ;data module number -maxmod equ 15 ;largest module number -fwfmsk equ 80h ;file write flag is high order modnum -namlen equ 15 ;name length -reccnt equ 15 ;record count field -dskmap equ 16 ;disk map field -lstfcb equ fcblen-1 -nxtrec equ fcblen -ranrec equ nxtrec+1 ;random record field (2 bytes) - -; reserved file indicators -rofile equ 9 ;high order of first type char -invis equ 10 ;invisible file in dir command -; equ 11 ;reserved - -; utility functions for file access - -dm$position: ;compute disk map position for vrecord to HL - ld hl,blkshf - ld c,(hl) ;shift count to C - ld a,(vrecord) ;current virtual record to A -dmpos0: or a - rra - dec c - jp nz,dmpos0 - ;A = shr(vrecord,blkshf) = vrecord/2**(sect/block) - ld b,a ;save it for later addition - ld a,8 - sub (hl) ;8-blkshf to accumulator - ld c,a ;extent shift count in register c - ld a,(extval) ;extent value ani extmsk -dmpos1: - ;blkshf = 3,4,5,6,7, C=5,4,3,2,1 - ;shift is 4,3,2,1,0 - dec c - jp z,dmpos2 - or a - rla - jp dmpos1 - -dmpos2: ;arrive here with A = shl(ext and extmsk,7-blkshf) - add a,b ;add the previous shr(vrecord,blkshf) value - ;A is one of the following values, depending upon alloc - ;bks blkshf - ;1k 3 v/8 + extval * 16 - ;2k 4 v/16+ extval * 8 - ;4k 5 v/32+ extval * 4 - ;8k 6 v/64+ extval * 2 - ;16k 7 v/128+extval * 1 - ret ;with dm$position in A - -getdm: ;return disk map value from position given by BC - ld hl,(info) ;base address of file control block - ld de,dskmap - add hl,de ;HL =.diskmap - add hl,bc ;index by a single byte value - ld a,(single) ;single byte/map entry? - or a - jp z,getdmd ;get disk map single byte - ld l,(hl) - ld h,0 - ret ;with HL=00bb -getdmd: - add hl,bc ;HL=.fcb(dm+i*2) - ;double precision value returned - ld e,(hl) - inc hl - ld d,(hl) - ex de,hl - ret - -index: ;compute disk block number from current fcb - call dm$position ;0...15 in register A - ld c,a - ld b,0 - call getdm ;value to HL - ld (arecord),hl - ret - -allocated: ;called following index to see if block allocated - ld hl,(arecord) - ld a,l - or h - ret - -atran: ;compute actual record address, assuming index called - ld a,(blkshf) ;shift count to reg A - ld hl,(arecord) -atran0: add hl,hl - dec a - jp nz,atran0 ;shl(arecord,blkshf) - ld (arecord1),hl ;save shifted block # - ld a,(blkmsk) - ld c,a ;mask value to C - ld a,(vrecord) - and c ;masked value in A - or l - ld l,a ;to HL - ld (arecord),hl ;arecord=HL or (vrecord and blkmsk) - ret - -getexta: ;get current extent field address to A - ld hl,(info) - ld de,extnum - add hl,de ;HL=.fcb(extnum) - ret - -getfcba: ;compute reccnt and nxtrec addresses for get/setfcb - ld hl,(info) - ld de,reccnt - add hl,de - ex de,hl ;DE=.fcb(reccnt) - ld hl,nxtrec-reccnt - add hl,de ;HL=.fcb(nxtrec) - ret - -getfcb: ;set variables from currently addressed fcb - call getfcba ;addresses in DE, HL - ld a,(hl) - ld (vrecord),a ;vrecord=fcb(nxtrec) - ex de,hl - ld a,(hl) - ld (rcount),a ;rcount=fcb(reccnt) - call getexta ;HL=.fcb(extnum) - ld a,(extmsk) ;extent mask to a - and (hl) ;fcb(extnum) and extmsk - ld (extval),a - ret - -setfcb: ;place values back into current fcb - call getfcba ;addresses to DE, HL - ld a,(seqio) - cp 02 - jp nz,setfcb1 - xor a ;check ranfill -setfcb1: - ld c,a ;=1 if sequential i/o - ld a,(vrecord) - add a,c - ld (hl),a ;fcb(nxtrec)=vrecord+seqio - ex de,hl - ld a,(rcount) - ld (hl),a ;fcb(reccnt)=rcount - ret - -hlrotr: ;hl rotate right by amount C - inc c ;in case zero -hlrotr0: - dec c - ret z ;return when zero - ld a,h - or a - rra - ld h,a ;high byte - ld a,l - rra - ld l,a ;low byte - jp hlrotr0 - -compute$cs: ;compute checksum for current directory buffer - ld c,recsiz ;size of directory buffer - ld hl,(buffa) ;current directory buffer - xor a ;clear checksum value -computecs0: - add a,(hl) - inc hl - dec c ;cs=cs+buff(recsiz-C) - jp nz,computecs0 - ret ;with checksum in A - -hlrotl: ;rotate the mask in HL by amount in C - inc c ;may be zero -hlrotl0: - dec c - ret z ;return if zero - add hl,hl - jp hlrotl0 - -set$cdisk: ;set a "1" value in curdsk position of BC - push bc ;save input parameter - ld a,(curdsk) - ld c,a ;ready parameter for shift - ld hl,1 ;number to shift - call hlrotl ;HL = mask to integrate - pop bc ;original mask - ld a,c - or l - ld l,a - ld a,b - or h - ld h,a ;HL = mask or rol(1,curdsk) - ret - -nowrite: ;return true if dir checksum difference occurred - ld hl,(rodsk) - ld a,(curdsk) - ld c,a - call hlrotr - ld a,l - and 1b - ret ;non zero if nowrite - -set$ro: ;set current disk to read only - ld hl,rodsk - ld c,(hl) - inc hl - ld b,(hl) - call set$cdisk ;sets bit to 1 - ld (rodsk),hl - ;high water mark in directory goes to max - ld hl,(dirmax) - inc hl - ex de,hl ;DE = directory max - ld hl,(cdrmaxa) ;HL = .cdrmax - ld (hl),e - inc hl - ld (hl),d ;cdrmax = dirmax - ret - -check$rodir: ;check current directory element for read/only status - call getdptra ;address of element - -check$rofile: ;check current buff(dptr) or fcb(0) for r/o status - ld de,rofile - add hl,de ;offset to ro bit - ld a,(hl) - rla - ret nc ;return if not set - ld hl,roferr - jp goerr -; jp rof$error ;exit to read only disk message - - -check$write: ;check for write protected disk - call nowrite - ret z ;ok to write if not rodsk - ld hl,roderr - jp goerr -; jp rod$error ;read only disk error - -getdptra: ;compute the address of a directory element at - ;positon dptr in the buffer - ld hl,(buffa) - ld a,(dptr) -addh: ;HL = HL + A - add a,l - ld l,a - ret nc - ;overflow to H - inc h - ret - - -getmodnum: ;compute the address of the module number - ;bring module number to accumulator - ;(high order bit is fwf (file write flag) - ld hl,(info) - ld de,modnum - add hl,de ;HL=.fcb(modnum) - ld a,(hl) - ret ;A=fcb(modnum) - -clrmodnum: ;clear the module number field for user open/make - call getmodnum - ld (hl),0 ;fcb(modnum)=0 - ret - -setfwf: call getmodnum ;HL=.fcb(modnum), A=fcb(modnum) - ;set fwf (file write flag) to "1" - or fwfmsk - ld (hl),a ;fcb(modnum)=fcb(modnum) or 80h - ;also returns non zero in accumulator - ret - - -compcdr: ;return cy if cdrmax > dcnt - ld hl,(dcnt) - ex de,hl ;DE = directory counter - ld hl,(cdrmaxa) ;HL=.cdrmax - ld a,e - sub (hl) ;low(dcnt) - low(cdrmax) - inc hl ;HL = .cdrmax+1 - ld a,d - sbc a,(hl) ;hig(dcnt) - hig(cdrmax) - ;condition dcnt - cdrmax produces cy if cdrmax>dcnt - ret - -setcdr: ;if not (cdrmax > dcnt) then cdrmax = dcnt+1 - call compcdr - ret c ;return if cdrmax > dcnt - ;otherwise, HL = .cdrmax+1, DE = dcnt - inc de - ld (hl),d - dec hl - ld (hl),e - ret - -subdh: ;compute HL = DE - HL - ld a,e - sub l - ld l,a - ld a,d - sbc a,h - ld h,a - ret - -newchecksum: - ld c,true ;drop through to compute new checksum -checksum: ;compute current checksum record and update the - ;directory element if C=true, or check for = if not - ;drec < chksiz? - ld hl,(drec) - ex de,hl - ld hl,(chksiz) - call subdh ;DE-HL - ret nc ;skip checksum if past checksum vector size - ;drec < chksiz, so continue - push bc ;save init flag - call compute$cs ;check sum value to A - ld hl,(checka) ;address of check sum vector - ex de,hl - ld hl,(drec) ;value of drec - add hl,de ;HL = .check(drec) - pop bc ;recall true=0ffh or false=00 to C - inc c ;0ffh produces zero flag - jp z,initial$cs - ;not initializing, compare - cp (hl) ;compute$cs=check(drec)? - ret z ;no message if ok - ;checksum error, are we beyond - ;the end of the disk? - call compcdr - ret nc ;no message if so - call set$ro ;read/only disk set - ret - -initial$cs: ;initializing the checksum - ld (hl),a - ret - - -wrdir: ;write the current directory entry, set checksum - call newchecksum ;initialize entry - call setdir ;directory dma - ld c,1 ;indicates a write directory operation - call wrbuff ;write the buffer - jp setdata ;to data dma address -; ret -rd$dir: ;read a directory entry into the directory buffer - call setdir ;directory dma - call rdbuff ;directory record loaded - ;jmp setdata to data dma address -; ret -setdata: ;set data dma address - ld hl,dmaad - jp setdma ;to complete the call - -setdir: ;set directory dma address - ld hl,buffa ;jmp setdma to complete call - -setdma: ;HL=.dma address to set (i.e., buffa or dmaad) - ld c,(hl) - inc hl - ld b,(hl) ;parameter ready - jp setdmaf - -dir$to$user: ;copy the directory entry to the user buffer - ;after call to search or searchn by user code - ld hl,(buffa) - ex de,hl ;source is directory buffer - ld hl,(dmaad) ;destination is user dma address - ld c,recsiz ;copy entire record - jp move -; ret - -end$of$dir: ;return zero flag if at end of directory, non zero - ;if not at end (end of dir if dcnt = 0ffffh) - ld hl,dcnt - ld a,(hl) ;may be 0ffh - inc hl - cp (hl) ;low(dcnt) = high(dcnt)? - ret nz ;non zero returned if different - ;high and low the same, = 0ffh? - inc a ;0ffh becomes 00 if so - ret - -set$end$dir: ;set dcnt to the end of the directory - ld hl,enddir - ld (dcnt),hl - ret - -read$dir: ;read next directory entry, with C=true if initializing - ld hl,(dirmax) - ex de,hl ;in preparation for subtract - ld hl,(dcnt) - inc hl - ld (dcnt),hl ;dcnt=dcnt+1 - ;continue while dirmax >= dcnt (dirmax-dcnt no cy) - call subdh ;DE-HL - jp nc,read$dir0 - ;yes, set dcnt to end of directory - jp set$end$dir -; ret - -read$dir0: ;not at end of directory, seek next element - ;initialization flag is in C - ld a,(dcnt) - and dskmsk ;low(dcnt) and dskmsk - ld b,fcbshf ;to multiply by fcb size -read$dir1: - add a,a - dec b - jp nz,read$dir1 - ;A = (low(dcnt) and dskmsk) shl fcbshf - ld (dptr),a ;ready for next dir operation - or a - ret nz ;return if not a new record - push bc ;save initialization flag C - call seek$dir ;seek proper record - call rd$dir ;read the directory record - pop bc ;recall initialization flag - jp checksum ;checksum the directory elt -; ret - - -getallocbit: ;given allocation vector position BC, return with byte - ;containing BC shifted so that the least significant - ;bit is in the low order accumulator position. HL is - ;the address of the byte for possible replacement in - ;memory upon return, and D contains the number of shifts - ;required to place the returned value back into position - ld a,c - and 111b - inc a - ld e,a - ld d,a - ;d and e both contain the number of bit positions to shift - ld a,c - rrca - rrca - rrca - and 11111b - ld c,a ;C shr 3 to C - ld a,b - add a,a - add a,a - add a,a - add a,a - add a,a ;B shl 5 - or c - ld c,a ;bbbccccc to C - ld a,b - rrca - rrca - rrca - and 11111b - ld b,a ;BC shr 3 to BC - ld hl,(alloca) ;base address of allocation vector - add hl,bc - ld a,(hl) ;byte to A, hl = .alloc(BC shr 3) - ;now move the bit to the low order position of A -rotl: rlca - dec e - jp nz,rotl - ret - - -set$alloc$bit: ;BC is the bit position of ALLOC to set or reset. The - ;value of the bit is in register E. - push de - call getallocbit ;shifted val A, count in D - and 11111110b ;mask low bit to zero (may be set) - pop bc - or c ;low bit of C is masked into A -; jp rotr ;to rotate back into proper position -; ret -rotr: - ;byte value from ALLOC is in register A, with shift count - ;in register C (to place bit back into position), and - ;target ALLOC position in registers HL, rotate and replace - rrca - dec d - jp nz,rotr ;back into position - ld (hl),a ;back to ALLOC - ret - -scandm: ;scan the disk map addressed by dptr for non-zero - ;entries, the allocation vector entry corresponding - ;to a non-zero entry is set to the value of C (0,1) - call getdptra ;HL = buffa + dptr - ;HL addresses the beginning of the directory entry - ld de,dskmap - add hl,de ;hl now addresses the disk map - push bc ;save the 0/1 bit to set - ld c,fcblen-dskmap+1;size of single byte disk map + 1 -scandm0: ;loop once for each disk map entry - pop de ;recall bit parity - dec c - ret z ;all done scanning? - ;no, get next entry for scan - push de ;replace bit parity - ld a,(single) - or a - jp z,scandm1 - ;single byte scan operation - push bc ;save counter - push hl ;save map address - ld c,(hl) - ld b,0 ;BC=block# - jp scandm2 - -scandm1: ;double byte scan operation - dec c ;count for double byte - push bc ;save counter - ld c,(hl) - inc hl - ld b,(hl) ;BC=block# - push hl ;save map address -scandm2: ;arrive here with BC=block#, E=0/1 - ld a,c - or b ;skip if = 0000 - jp z,scanm3 - ld hl,(maxall) ;check invalid index - ld a,l - sub c - ld a,h - sbc a,b ;maxall - block# - call nc,set$alloc$bit - ;bit set to 0/1 -scanm3: pop hl - inc hl ;to next bit position - pop bc ;recall counter - jp scandm0 ;for another item - -initialize: ;initialize the current disk - ;lret = false ;set to true if $ file exists - ;compute the length of the allocation vector - 2 - ld hl,(maxall) - ld c,3 ;perform maxall/8 - ;number of bytes in alloc vector is (maxall/8)+1 - call hlrotr - inc hl ;HL = maxall/8+1 - ld b,h - ld c,l ;count down BC til zero - ld hl,(alloca) ;base of allocation vector - ;fill the allocation vector with zeros -initial0: - ld (hl),0 - inc hl ;alloc(i)=0 - dec bc ;count length down - ld a,b - or c - jp nz,initial0 - ;set the reserved space for the directory - ld hl,(dirblk) - ex de,hl - ld hl,(alloca) ;HL=.alloc() - ld (hl),e - inc hl - ld (hl),d ;sets reserved directory blks - ;allocation vector initialized, home disk - call home - ;cdrmax = 3 (scans at least one directory record) - ld hl,(cdrmaxa) - ld (hl),3 - inc hl - ld (hl),0 - ;cdrmax = 0000 - call set$end$dir ;dcnt = enddir - ;read directory entries and check for allocated storage -initial2: - ld c,true - call read$dir - call end$of$dir - ret z ;return if end of directory - ;not end of directory, valid entry? - call getdptra ;HL = buffa + dptr - ld a,empty - cp (hl) - jp z,initial2 ;go get another item - ;not empty, user code the same? - ld a,(usrcode) - cp (hl) - jp nz,pdollar - ;same user code, check for '$' submit - inc hl - ld a,(hl) ;first character - sub '$' ;dollar file? - jp nz,pdollar - ;dollar file found, mark in lret - dec a - ld (lret),a ;lret = 255 -pdollar: ;now scan the disk map for allocated blocks - ld c,1 ;set to allocated - call scandm - call setcdr ;set cdrmax to dcnt - jp initial2 ;for another entry - -copy$dirloc: ;copy directory location to lret following - ;delete, rename, ... ops - ld a,(dirloc) - jp sta$ret -; ret - -compext: ;compare extent# in A with that in C, return nonzero - ;if they do not match - push bc ;save C's original value - push af - ld a,(extmsk) - cpl - ld b,a - ;B has negated form of extent mask - ld a,c - and b - ld c,a ;low bits removed from C - pop af - and b ;low bits removed from A - sub c - and maxext ;set flags - pop bc ;restore original values - ret - -search: ;search for directory element of length C at info - ld a,0ffh - ld (dirloc),a ;changed if actually found - ld hl,searchl - ld (hl),c ;searchl = C - ld hl,(info) - ld (searcha),hl ;searcha = info - call set$end$dir ;dcnt = enddir - call home ;to start at the beginning - ;(drop through to searchn) - -searchn: ;search for the next directory element, assuming - ;a previous call on search which sets searcha and - ;searchl - ld c,false - call read$dir ;read next dir element - call end$of$dir - jp z,search$fin ;skip to end if so - ;not end of directory, scan for match - ld hl,(searcha) - ex de,hl ;DE=beginning of user fcb - ld a,(de) ;first character - cp empty ;keep scanning if empty - jp z,searchnext - ;not empty, may be end of logical directory - push de ;save search address - call compcdr ;past logical end? - pop de ;recall address - jp nc,search$fin ;artificial stop -searchnext: - call getdptra ;HL = buffa+dptr - ld a,(searchl) - ld c,a ;length of search to c - ld b,0 ;b counts up, c counts down -searchloop: - ld a,c - or a - jp z,endsearch - ld a,(de) - cp '?' - jp z,searchok ;? matches all - ;scan next character if not ubytes - ld a,b - cp ubytes - jp z,searchok - ;not the ubytes field, extent field? - cp extnum ;may be extent field - ld a,(de) ;fcb character - jp z,searchext ;skip to search extent - sub (hl) - and 7fh ;mask-out flags/extent modulus - jp nz,searchn ;skip if not matched - jp searchok ;matched character - -searchext: ;A has fcb character - ;attempt an extent # match - push bc ;save counters - ld c,(hl) ;directory character to c - call compext ;compare user/dir char - pop bc ;recall counters - jp nz,searchn ;skip if no match -searchok: ;current character matches - inc de - inc hl - inc b - dec c - jp searchloop - -endsearch: ;entire name matches, return dir position - ld a,(dcnt) - and dskmsk - ld (lret),a - ;lret = low(dcnt) and 11b - ld hl,dirloc - ld a,(hl) - rla - ret nc ;dirloc=0ffh? - ;yes, change it to 0 to mark as found - xor a - ld (hl),a ;dirloc=0 - ret - -search$fin: ;end of directory, or empty name - call set$end$dir ;may be artifical end - ld a,255 - jp sta$ret - -delete: ;delete the currently addressed file - call check$write ;write protected? - ld c,extnum - call search ;search through file type -delete0: - ;loop while directory matches - call end$of$dir - ret z ;stop if end - ;set each non zero disk map entry to 0 - ;in the allocation vector - ;may be r/o file - call check$rodir ;ro disk error if found - call getdptra ;HL=.buff(dptr) - ld (hl),empty - ld c,0 - call scandm ;alloc elts set to 0 - call wrdir ;write the directory - call searchn ;to next element - jp delete0 ;for another record - -get$block: ;given allocation vector position BC, find the zero bit - ;closest to this position by searching left and right. - ;if found, set the bit to one and return the bit position - ;in hl. if not found (i.e., we pass 0 on the left, or - ;maxall on the right), return 0000 in hl - ld d,b - ld e,c ;copy of starting position to de -lefttst: - ld a,c - or b - jp z,righttst ;skip if left=0000 - ;left not at position zero, bit zero? - dec bc - push de - push bc ;left,right pushed - call getallocbit - rra - jp nc,retblock ;return block number if zero - ;bit is one, so try the right - pop bc - pop de ;left, right restored -righttst: - ld hl,(maxall) ;value of maximum allocation# - ld a,e - sub l - ld a,d - sbc a,h ;right=maxall? - jp nc,retblock0 ;return block 0000 if so - inc de - push bc - push de ;left, right pushed - ld b,d - ld c,e ;ready right for call - call getallocbit - rra - jp nc,retblock ;return block number if zero - pop de - pop bc ;restore left and right pointers - jp lefttst ;for another attempt -retblock: - rla - inc a ;bit back into position and set to 1 - ;d contains the number of shifts required to reposition - call rotr ;move bit back to position and store - pop hl - pop de ;HL returned value, DE discarded - ret - -retblock0: ;cannot find an available bit, return 0000 - ld a,c - or b - jp nz,lefttst ;also at beginning - ld hl,0000h - ret - -copy$fcb: ;copy the entire file control block - ld c,0 - ld e,fcblen ;start at 0, to fcblen-1 -; jp copy$dir - -copy$dir: ;copy fcb information starting at C for E bytes - ;into the currently addressed directory entry - push de ;save length for later - ld b,0 ;double index to BC - ld hl,(info) ;HL = source for data - add hl,bc - ex de,hl ;DE=.fcb(C), source for copy - call getdptra ;HL=.buff(dptr), destination - pop bc ;DE=source, HL=dest, C=length - call move ;data moved -seek$copy: ;enter from close to seek and copy current element - call seek$dir ;to the directory element - jp wrdir ;write the directory element -; ret -rename: ;rename the file described by the first half of - ;the currently addressed file control block. the - ;new name is contained in the last half of the - ;currently addressed file conrol block. the file - ;name and type are changed, but the reel number - ;is ignored. the user number is identical - call check$write ;may be write protected - ;search up to the extent field - ld c,extnum - call search - ;copy position 0 - ld hl,(info) - ld a,(hl) ;HL=.fcb(0), A=fcb(0) - ld de,dskmap - add hl,de ;HL=.fcb(dskmap) - ld (hl),a ;fcb(dskmap)=fcb(0) - ;assume the same disk drive for new named file -rename0: - call end$of$dir - ret z ;stop at end of dir - ;not end of directory, rename next element - call check$rodir ;may be read-only file - ld c,dskmap - ld e,extnum - call copy$dir - ;element renamed, move to next - call searchn - jp rename0 - -indicators: ;set file indicators for current fcb - ld c,extnum - call search ;through file type -indic0: call end$of$dir - ret z ;stop at end of dir - ;not end of directory, continue to change - ld c,0 - ld e,extnum ;copy name - call copy$dir - call searchn - jp indic0 - -open: ;search for the directory entry, copy to fcb - ld c,namlen - call search - call end$of$dir - ret z ;return with lret=255 if end - ;not end of directory, copy fcb information -open$copy: ;(referenced below to copy fcb info) - call getexta - ld a,(hl) - push af - push hl ;save extent# - call getdptra - ex de,hl ;DE = .buff(dptr) - ld hl,(info) ;HL=.fcb(0) - ld c,nxtrec ;length of move operation - push de ;save .buff(dptr) - call move ;from .buff(dptr) to .fcb(0) - ;note that entire fcb is copied, including indicators - call setfwf ;sets file write flag - pop de - ld hl,extnum - add hl,de ;HL=.buff(dptr+extnum) - ld c,(hl) ;C = directory extent number - ld hl,reccnt - add hl,de ;HL=.buff(dptr+reccnt) - ld b,(hl) ;B holds directory record count - pop hl - pop af - ld (hl),a ;restore extent number - ;HL = .user extent#, B = dir rec cnt, C = dir extent# - ;if user ext < dir ext then user := 128 records - ;if user ext = dir ext then user := dir records - ;if user ext > dir ext then user := 0 records - ld a,c - cp (hl) - ld a,b ;ready dir reccnt - jp z,open$rcnt ;if same, user gets dir reccnt - ld a,0 - jp c,open$rcnt ;user is larger - ld a,128 ;directory is larger -open$rcnt: ;A has record count to fill - ld hl,(info) - ld de,reccnt - add hl,de - ld (hl),a - ret - -mergezero: ;HL = .fcb1(i), DE = .fcb2(i), - ;if fcb1(i) = 0 then fcb1(i) := fcb2(i) - ld a,(hl) - inc hl - or (hl) - dec hl - ret nz ;return if = 0000 - ld a,(de) - ld (hl),a - inc de - inc hl ;low byte copied - ld a,(de) - ld (hl),a - dec de - dec hl ;back to input form - ret - -close: ;locate the directory element and re-write it - xor a - ld (lret),a - ld (dcnt),a - ld (dcnt+1),a - call nowrite - ret nz ;skip close if r/o disk - ;check file write flag - 0 indicates written - call getmodnum ;fcb(modnum) in A - and fwfmsk - ret nz ;return if bit remains set - ld c,namlen - call search ;locate file - call end$of$dir - ret z ;return if not found - ;merge the disk map at info with that at buff(dptr) - ld bc,dskmap - call getdptra - add hl,bc - ex de,hl ;DE is .buff(dptr+16) - ld hl,(info) - add hl,bc ;DE=.buff(dptr+16), HL=.fcb(16) - ld c,fcblen-dskmap;length of single byte dm -merge0: ld a,(single) - or a - jp z,merged ;skip to double - ;this is a single byte map - ;if fcb(i) = 0 then fcb(i) = buff(i) - ;if buff(i) = 0 then buff(i) = fcb(i) - ;if fcb(i) <> buff(i) then error - ld a,(hl) - or a - ld a,(de) - jp nz,fcbnzero - ;fcb(i) = 0 - ld (hl),a ;fcb(i) = buff(i) -fcbnzero: - or a - jp nz,buffnzero - ;buff(i) = 0 - ld a,(hl) - ld (de),a ;buff(i)=fcb(i) -buffnzero: - cp (hl) - jp nz,mergerr ;fcb(i) = buff(i)? - jp dmset ;if merge ok - -merged: ;this is a double byte merge operation - call mergezero ;buff = fcb if buff 0000 - ex de,hl - call mergezero - ex de,hl ;fcb = buff if fcb 0000 - ;they should be identical at this point - ld a,(de) - cp (hl) - jp nz,mergerr ;low same? - inc de - inc hl ;to high byte - ld a,(de) - cp (hl) - jp nz,mergerr ;high same? - ;merge operation ok for this pair - dec c ;extra count for double byte -dmset: inc de - inc hl ;to next byte position - dec c - jp nz,merge0 ;for more - ;end of disk map merge, check record count - ;DE = .buff(dptr)+32, HL = .fcb(32) - ld bc,-(fcblen-extnum) - add hl,bc - ex de,hl - add hl,bc - ;DE = .fcb(extnum), HL = .buff(dptr+extnum) - ld a,(de) ;current user extent number - ;if fcb(ext) >= buff(fcb) then - ;buff(ext) := fcb(ext), buff(rec) := fcb(rec) - cp (hl) - jp c,endmerge - ;fcb extent number >= dir extent number - ld (hl),a ;buff(ext) = fcb(ext) - ;update directory record count field - ld bc,reccnt-extnum - add hl,bc - ex de,hl - add hl,bc - ;DE=.buff(reccnt), HL=.fcb(reccnt) - ld a,(hl) - ld (de),a ;buff(reccnt)=fcb(reccnt) -endmerge: - ld a,true - ld (fcb$copied),a ;mark as copied - jp seek$copy ;ok to "wrdir" here - 1.4 compat - ; ret - -mergerr: ;elements did not merge correctly - ld hl,lret - dec (hl) ;=255 non zero flag set - ret - -make: ;create a new file by creating a directory entry - ;then opening the file - call check$write ;may be write protected - ld hl,(info) - push hl ;save fcb address, look for e5 - ld hl,efcb - ld (info),hl ;info = .empty - ld c,1 - call search ;length 1 match on empty entry - call end$of$dir ;zero flag set if no space - pop hl ;recall info address - ld (info),hl ;in case we return here - ret z ;return with error condition 255 if not found - ex de,hl ;DE = info address - ;clear the remainder of the fcb - ld hl,namlen - add hl,de ;HL=.fcb(namlen) - ld c,fcblen-namlen ;number of bytes to fill - xor a ;clear accumulator to 00 for fill -make0: ld (hl),a - inc hl - dec c - jp nz,make0 - ld hl,ubytes - add hl,de ;HL = .fcb(ubytes) - ld (hl),a ;fcb(ubytes) = 0 - call setcdr ;may have extended the directory - ;now copy entry to the directory - call copy$fcb - ;and set the file write flag to "1" - jp setfwf -; ret - -open$reel: ;close the current extent, and open the next one - ;if possible. RMF is true if in read mode - xor a - ld (fcb$copied),a ;set true if actually copied - call close ;close current extent - ;lret remains at enddir if we cannot open the next ext - call end$of$dir - ret z ;return if end - ;increment extent number - ld hl,(info) - ld bc,extnum - add hl,bc ;HL=.fcb(extnum) - ld a,(hl) - inc a - and maxext - ld (hl),a ;fcb(extnum)=++1 - jp z,open$mod ;move to next module if zero - ;may be in the same extent group - ld b,a - ld a,(extmsk) - and b - ;if result is zero, then not in the same group - ld hl,fcb$copied ;true if the fcb was copied to directory - and (hl) ;produces a 00 in accumulator if not written - jp z,open$reel0 ;go to next physical extent - ;result is non zero, so we must be in same logical ext - jp open$reel1 ;to copy fcb information -open$mod: ;extent number overflow, go to next module - ld bc,modnum-extnum - add hl,bc ;HL=.fcb(modnum) - inc (hl) ;fcb(modnum)=++1 - ;module number incremented, check for overflow - ld a,(hl) - and maxmod ;mask high order bits - jp z,open$r$err ;cannot overflow to zero - ;otherwise, ok to continue with new module -open$reel0: - ld c,namlen - call search ;next extent found? - call end$of$dir - jp nz,open$reel1 - ;end of file encountered - ld a,(rmf) - inc a ;0ffh becomes 00 if read - jp z,open$r$err ;sets lret = 1 - ;try to extend the current file - call make - ;cannot be end of directory - call end$of$dir - jp z,open$r$err ;with lret = 1 - jp open$reel2 - -open$reel1: ;not end of file, open - call open$copy -open$reel2: - call getfcb ;set parameters - xor a - jp sta$ret ;lret = 0 -; ret ;with lret = 0 - -open$r$err: ;cannot move to next extent of this file - call setlret1 ;lret = 1 - jp setfwf ;ensure that it will not be closed -; ret - -seqdiskread: ;sequential disk read operation - ld a,1 - ld (seqio),a - ;drop through to diskread - -diskread: ;(may enter from seqdiskread) - ld a,true - ld (rmf),a ;read mode flag = true (open$reel) - ;read the next record from the current fcb - call getfcb ;sets parameters for the read - ld a,(vrecord) - ld hl,rcount - cp (hl) ;vrecord-rcount - ;skip if rcount > vrecord - jp c,recordok - ;not enough records in the extent - ;record count must be 128 to continue - cp 128 ;vrecord = 128? - jp nz,diskeof ;skip if vrecord<>128 - call open$reel ;go to next extent if so - xor a - ld (vrecord),a ;vrecord=00 - ;now check for open ok - ld a,(lret) - or a - jp nz,diskeof ;stop at eof -recordok: ;arrive with fcb addressing a record to read - call index - ;error 2 if reading unwritten data - ;(returns 1 to be compatible with 1.4) - call allocated ;arecord=0000? - jp z,diskeof - ;record has been allocated, read it - call atran ;arecord now a disk address - call seek ;to proper track,sector - call rdbuff ;to dma address - jp setfcb ;replace parameter -; ret - -diskeof: - jp setlret1 ;lret = 1 -; ret - -seqdiskwrite: ;sequential disk write - ld a,1 - ld (seqio),a - ;drop through to diskwrite - -diskwrite: ;(may enter here from seqdiskwrite above) - ld a,false - ld (rmf),a ;read mode flag - ;write record to currently selected file - call check$write ;in case write protected - ld hl,(info) ;HL = .fcb(0) - call check$rofile ;may be a read-only file - call getfcb ;to set local parameters - ld a,(vrecord) - cp lstrec+1 ;vrecord-128 - ;skip if vrecord > lstrec - ;vrecord = 128, cannot open next extent - jp nc,setlret1 ;lret=1 -diskwr0: ;can write the next record, so continue - call index - call allocated - ld c,0 ;marked as normal write operation for wrbuff - jp nz,diskwr1 - ;not allocated - ;the argument to getblock is the starting - ;position for the disk search, and should be - ;the last allocated block for this file, or - ;the value 0 if no space has been allocated - call dm$position - ld (dminx),a ;save for later - ld bc,0000h ;may use block zero - or a - jp z,nopblock ;skip if no previous block - ;previous block exists at A - ld c,a - dec bc ;previous block # in BC - call getdm ;previous block # to HL - ld b,h - ld c,l ;BC=prev block# -nopblock: ;BC = 0000, or previous block # - call get$block ;block # to HL - ;arrive here with block# or zero - ld a,l - or h - jp nz,blockok - ;cannot find a block to allocate - ld a,2 - jp sta$ret ;lret=2 - -blockok: ;allocated block number is in HL - ld (arecord),hl - ex de,hl ;block number to DE - ld hl,(info) - ld bc,dskmap - add hl,bc ;HL=.fcb(dskmap) - ld a,(single) - or a ;set flags for single byte dm - ld a,(dminx) ;recall dm index - jp z,allocwd ;skip if allocating word - ;allocating a byte value - call addh - ld (hl),e ;single byte alloc - jp diskwru ;to continue - -allocwd: ;allocate a word value - ld c,a - ld b,0 ;double(dminx) - add hl,bc - add hl,bc ;HL=.fcb(dminx*2) - ld (hl),e - inc hl - ld (hl),d ;double wd -diskwru: ;disk write to previously unallocated block - ld c,2 ;marked as unallocated write -diskwr1: ;continue the write operation of no allocation error - ;C = 0 if normal write, 2 if to prev unalloc block - ld a,(lret) - or a - ret nz ;stop if non zero returned value - push bc ;save write flag - call atran ;arecord set - ld a,(seqio) - dec a - dec a - jp nz,diskwr11 - pop bc - push bc - ld a,c - dec a - dec a - jp nz,diskwr11 ;old allocation - push hl ;arecord in hl ret from atran - ld hl,(buffa) - ld d,a ;zero buffa & fill -fill0: ld (hl),a - inc hl - inc d - jp p,fill0 - call setdir - ld hl,(arecord1) - ld c,2 -fill1: ld (arecord),hl - push bc - call seek - pop bc - call wrbuff ;write fill record - ld hl,(arecord) ;restore last record - ld c,0 ;change allocate flag - ld a,(blkmsk) - ld b,a - and l - cp b - inc hl - jp nz,fill1 ;cont until cluster is zeroed - pop hl - ld (arecord),hl - call setdata -diskwr11: - call seek ;to proper file position - pop bc - push bc ;restore/save write flag (C=2 if new block) - call wrbuff ;written to disk - pop bc ;C = 2 if a new block was allocated, 0 if not - ;increment record count if rcount<=vrecord - ld a,(vrecord) - ld hl,rcount - cp (hl) ;vrecord-rcount - jp c,diskwr2 - ;rcount <= vrecord - ld (hl),a - inc (hl) ;rcount = vrecord+1 - ld c,2 ;mark as record count incremented -diskwr2: ;A has vrecord, C=2 if new block or new record# - dec c - dec c - jp nz,noupdate - push af ;save vrecord value - call getmodnum ;HL=.fcb(modnum), A=fcb(modnum) - ;reset the file write flag to mark as written fcb - and (not fwfmsk) and 0ffh;bit reset - ld (hl),a ;fcb(modnum) = fcb(modnum) and 7fh - pop af ;restore vrecord -noupdate: ;check for end of extent, if found attempt to open - ;next extent in preparation for next write - cp lstrec ;vrecord=lstrec? - jp nz,diskwr3 ;skip if not - ;may be random access write, if so we are done - ;change next - ld a,(seqio) - cp 1 - jp nz,diskwr3 ;skip next extent open op - ;update current fcb before going to next extent - call setfcb - call open$reel ;rmf=false - ;vrecord remains at lstrec causing eof if - ;no more directory space is available - ld hl,lret - ld a,(hl) - or a - jp nz,nospace - ;space available, set vrecord=255 - dec a - ld (vrecord),a ;goes to 00 next time -nospace: - ld (hl),0 ;lret = 00 for returned value -diskwr3: - jp setfcb ;replace parameters -; ret - -rseek: ;random access seek operation, C=0ffh if read mode - ;fcb is assumed to address an active file control block - ;(modnum has been set to 1100$0000b if previous bad seek) - xor a - ld (seqio),a ;marked as random access operation -rseek1: push bc ;save r/w flag - ld hl,(info) - ex de,hl ;DE will hold base of fcb - ld hl,ranrec - add hl,de ;HL=.fcb(ranrec) - ld a,(hl) - and 7fh - push af ;record number - ld a,(hl) - rla ;cy=lsb of extent# - inc hl - ld a,(hl) - rla - and 11111b ;A=ext# - ld c,a ;C holds extent number, record stacked - ld a,(hl) - rra - rra - rra - rra - and 1111b ;mod# - ld b,a ;B holds module#, C holds ext# - pop af ;recall sought record # - ;check to insure that high byte of ran rec = 00 - inc hl - ld l,(hl) ;l=high byte (must be 00) - inc l - dec l - ld l,6 ;zero flag, l=6 - ;produce error 6, seek past physical eod - jp nz,seekerr - ;otherwise, high byte = 0, A = sought record - ld hl,nxtrec - add hl,de ;HL = .fcb(nxtrec) - ld (hl),a ;sought rec# stored away - ;arrive here with B=mod#, C=ext#, DE=.fcb, rec stored - ;the r/w flag is still stacked. compare fcb values - ld hl,extnum - add hl,de - ld a,c ;A=seek ext# - sub (hl) - jp nz,ranclose ;tests for = extents - ;extents match, check mod# - ld hl,modnum - add hl,de - ld a,b ;B=seek mod# - ;could be overflow at eof, producing module# - ;of 90H or 10H, so compare all but fwf - sub (hl) - and 7fh - jp z,seekok ;same? -ranclose: - push bc - push de ;save seek mod#,ext#, .fcb - call close ;current extent closed - pop de - pop bc ;recall parameters and fill - ld l,3 ;cannot close error #3 - ld a,(lret) - inc a - jp z,badseek - ld hl,extnum - add hl,de - ld (hl),c ;fcb(extnum)=ext# - ld hl,modnum - add hl,de - ld (hl),b ;fcb(modnum)=mod# - call open ;is the file present? - ld a,(lret) - inc a - jp nz,seekok ;open successful? - ;cannot open the file, read mode? - pop bc ;r/w flag to c (=0ffh if read) - push bc ;everyone expects this item stacked - ld l,4 ;seek to unwritten extent #4 - inc c ;becomes 00 if read operation - jp z,badseek ;skip to error if read operation - ;write operation, make new extent - call make - ld l,5 ;cannot create new extent #5 - ld a,(lret) - inc a - jp z,badseek ;no dir space - ;file make operation successful -seekok: - pop bc ;discard r/w flag - xor a - jp sta$ret ;with zero set -badseek: ;fcb no longer contains a valid fcb, mark - ;with 1100$000b in modnum field so that it - ;appears as overflow with file write flag set - push hl ;save error flag - call getmodnum ;HL = .modnum - ld (hl),11000000b - pop hl ;and drop through -seekerr: - pop bc ;discard r/w flag - ld a,l - ld (lret),a ;lret=#, nonzero - ;setfwf returns non-zero accumulator for err - jp setfwf ;flag set, so subsequent close ok -; ret - -randiskread: ;random disk read operation - ld c,true ;marked as read operation - call rseek - call z,diskread ;if seek successful - ret - -randiskwrite: ;random disk write operation - ld c,false ;marked as write operation - call rseek - call z,diskwrite ;if seek successful - ret - -compute$rr: ;compute random record position for getfilesize/setrandom - ex de,hl - add hl,de - ;DE=.buf(dptr) or .fcb(0), HL = .f(nxtrec/reccnt) - ld c,(hl) - ld b,0 ;BC = 0000 0000 ?rrr rrrr - ld hl,extnum - add hl,de - ld a,(hl) - rrca - and 80h ;A=e000 0000 - add a,c - ld c,a - ld a,0 - adc a,b - ld b,a - ;BC = 0000 000? errrr rrrr - ld a,(hl) - rrca - and 0fh - add a,b - ld b,a - ;BC = 000? eeee errrr rrrr - ld hl,modnum - add hl,de - ld a,(hl) ;A=XXX? mmmm - add a,a - add a,a - add a,a - add a,a ;cy=? A=mmmm 0000 - push af - add a,b - ld b,a - ;cy=?, BC = mmmm eeee errr rrrr - push af ;possible second carry - pop hl ;cy = lsb of L - ld a,l ;cy = lsb of A - pop hl ;cy = lsb of L - or l ;cy/cy = lsb of A - and 1 ;A = 0000 000? possible carry-out - ret - -getfilesize: ;compute logical file size for current fcb - ld c,extnum - call search - ;zero the receiving ranrec field - ld hl,(info) - ld de,ranrec - add hl,de - push hl ;save position - ld (hl),d - inc hl - ld (hl),d - inc hl - ld (hl),d ;=00 00 00 -getsize: - call end$of$dir - jp z,setsize - ;current fcb addressed by dptr - call getdptra - ld de,reccnt ;ready for compute size - call compute$rr - ;A=0000 000? BC = mmmm eeee errr rrrr - ;compare with memory, larger? - pop hl - push hl ;recall, replace .fcb(ranrec) - ld e,a ;save cy - ld a,c - sub (hl) - inc hl ;ls byte - ld a,b - sbc a,(hl) - inc hl ;middle byte - ld a,e - sbc a,(hl) ;carry if .fcb(ranrec) > directory - jp c,getnextsize ;for another try - ;fcb is less or equal, fill from directory - ld (hl),e - dec hl - ld (hl),b - dec hl - ld (hl),c -getnextsize: - call searchn - jp getsize - -setsize: - pop hl ;discard .fcb(ranrec) - ret - -setrandom: ;set random record from the current file control block - ld hl,(info) - ld de,nxtrec ;ready params for computesize - call compute$rr ;DE=info, A=cy, BC=mmmm eeee errr rrrr - ld hl,ranrec - add hl,de ;HL = .fcb(ranrec) - ld (hl),c - inc hl - ld (hl),b - inc hl - ld (hl),a ;to ranrec - ret - -select: ;select disk info for subsequent input or output ops - ld hl,(dlog) - ld a,(curdsk) - ld c,a - call hlrotr - push hl - ex de,hl ;save it for test below, send to seldsk - call selectdisk - pop hl ;recall dlog vector - call z,sel$error ;returns true if select ok - ;is the disk logged in? - ld a,l - rra - ret c ;return if bit is set - ;disk not logged in, set bit and initialize - ld hl,(dlog) - ld c,l - ld b,h ;call ready - call set$cdisk - ld (dlog),hl ;dlog=set$cdisk(dlog) - jp initialize -; ret - -curselect: - ld a,(linfo) - ld hl,curdsk - cp (hl) - ret z ;skip if linfo=curdsk - ld (hl),a ;curdsk=info - jp select -; ret - -reselect: ;check current fcb to see if reselection necessary - ld a,true - ld (resel),a ;mark possible reselect - ld hl,(info) - ld a,(hl) ;drive select code - and 11111b ;non zero is auto drive select - dec a ;drive code normalized to 0..30, or 255 - ld (linfo),a ;save drive code - cp 30 - jp nc,noselect - ;auto select function, save curdsk - ld a,(curdsk) - ld (olddsk),a ;olddsk=curdsk - ld a,(hl) - ld (fcbdsk),a ;save drive code - and 11100000b - ld (hl),a ;preserve hi bits - call curselect -noselect: ;set user code - ld a,(usrcode) ;0...31 - ld hl,(info) - or (hl) - ld (hl),a - ret - -; individual function handlers -func12: ;return version number - ld a,dvers - jp sta$ret ;lret = dvers (high = 00) -; ret -; jp goback - -func13: ;reset disk system - initialize to disk 0 - ld hl,0 - ld (rodsk),hl - ld (dlog),hl - xor a - ld (curdsk),a ;note that usrcode remains unchanged - ld hl,tbuff - ld (dmaad),hl ;dmaad = tbuff - call setdata ;to data dma address - jp select -; ret -; jp goback - -func14 equ curselect ;select disk info -; ret -; jp goback - -func15: ;open file - call clrmodnum ;clear the module number - call reselect - jp open -; ret -; jp goback - -func16: ;close file - call reselect - jp close -; ret -; jp goback - -func17: ;search for first occurrence of a file - ld c,0 ;length assuming '?' true - ex de,hl ;was lhld info - ld a,(hl) - cp '?' ;no reselect if ? - jp z,qselect ;skip reselect if so - ;normal search - call getexta - ld a,(hl) - cp '?' ; - call nz,clrmodnum ;module number zeroed - call reselect - ld c,namlen -qselect: - call search - jp dir$to$user ;copy directory entry to user -; ret -; jp goback - -func18: ;search for next occurrence of a file name - ld hl,(searcha) - ld (info),hl - call reselect - call searchn - jp dir$to$user ;copy directory entry to user -; ret -; jp goback - -func19: ;delete a file - call reselect - call delete - jp copy$dirloc -; ret -; jp goback - -func20: ;read a file - call reselect - jp seqdiskread -; jp goback - -func21: ;write a file - call reselect - jp seqdiskwrite -; jp goback - -func22: ;make a file - call clrmodnum - call reselect - jp make -; ret -; jp goback - -func23: ;rename a file - call reselect - call rename - jp copy$dirloc -; ret -; jp goback - -func24: ;return the login vector - ld hl,(dlog) - jp sthl$ret -; ret -; jp goback - -func25: ;return selected disk number - ld a,(curdsk) - jp sta$ret -; ret -; jp goback - -func26: ;set the subsequent dma address to info - ex de,hl ;was lhld info - ld (dmaad),hl ;dmaad = info - jp setdata ;to data dma address -; ret -; jp goback - -func27: ;return the login vector address - ld hl,(alloca) - jp sthl$ret -; ret -; jp goback - -func28 equ set$ro - ;write protect current disk -; ret -; jp goback - -func29: ;return r/o bit vector - ld hl,(rodsk) - jp sthl$ret -; ret -; jp goback - -func30: ;set file indicators - call reselect - call indicators - jp copy$dirloc ;lret=dirloc -; ret -; jp goback - -func31: ;return address of disk parameter block - ld hl,(dpbaddr) -sthl$ret: - ld (aret),hl - ret -; jp goback - -func32: ;set user code - ld a,(linfo) - cp 0ffh - jp nz,setusrcode - ;interrogate user code instead - ld a,(usrcode) - jp sta$ret ;lret=usrcode -; ret -; jp goback - -setusrcode: - and 1fh - ld (usrcode),a - ret -; jp goback - -func33: ;random disk read operation - call reselect - jp randiskread ;to perform the disk read -; ret -; jp goback - -func34: ;random disk write operation - call reselect - jp randiskwrite ;to perform the disk write -; ret -; jp goback - -func35: ;return file size (0-65536) - call reselect - jp getfilesize -; ret -; jp goback - -func36 equ setrandom ;set random record -; ret -; jp goback - -func37: ld hl,(info) - ld a,l - cpl - ld e,a - ld a,h - cpl - ld hl,(dlog) - and h - ld d,a - ld a,l - and e - ld e,a - ld hl,(rodsk) - ex de,hl - ld (dlog),hl - ld a,l - and e - ld l,a - ld a,h - and d - ld h,a - ld (rodsk),hl - ret - -goback: ;arrive here at end of processing to return to user - ld a,(resel) - or a - jp z,retmon - ;reselection may have taken place - ld hl,(info) - ld (hl),0 ;fcb(0)=0 - ld a,(fcbdsk) - or a - jp z,retmon - ;restore disk number - ld (hl),a ;fcb(0)=fcbdsk - ld a,(olddsk) - ld (linfo),a - call curselect - -; return from the disk monitor -retmon: ld hl,(entsp) - ld sp,hl ;user stack restored - ld hl,(aret) - ld a,l - ld b,h ;BA = HL = aret - ret - -func38 equ func$ret -func39 equ func$ret -func40: ;random disk write with zero fill of unallocated block - call reselect - ld a,2 - ld (seqio),a - ld c,false - call rseek1 - call z,diskwrite ;if seek successful - ret - -; data areas - -; initialized data -efcb: db empty ;0e5=available dir entry -rodsk: dw 0 ;read only disk vector -dlog: dw 0 ;logged-in disks -dmaad: dw tbuff ;initial dma address - -; curtrka - alloca are set upon disk select -; (data must be adjacent, do not insert variables) -; (address of translate vector, not used) -cdrmaxa: - ds word ;pointer to cur dir max value -curtrka: - ds word ;current track address -curreca: - ds word ;current record address -buffa: ds word ;pointer to directory dma address -dpbaddr: - ds word ;current disk parameter block address -checka: ds word ;current checksum vector address -alloca: ds word ;current allocation vector address -addlist equ $-buffa ;address list size - -; sectpt - offset obtained from disk parm block at dpbaddr -; (data must be adjacent, do not insert variables) -sectpt: ds word ;sectors per track -blkshf: ds byte ;block shift factor -blkmsk: ds byte ;block mask -extmsk: ds byte ;extent mask -maxall: ds word ;maximum allocation number -dirmax: ds word ;largest directory number -dirblk: ds word ;reserved allocation bits for directory -chksiz: ds word ;size of checksum vector -offset: ds word ;offset tracks at beginning -dpblist equ $-sectpt ;size of area - -; local variables -tranv: ds word ;address of translate vector -fcb$copied: - ds byte ;set true if copy$fcb called -rmf: ds byte ;read mode flag for open$reel -dirloc: ds byte ;directory flag in rename, etc. -seqio: ds byte ;1 if sequential i/o -linfo: ds byte ;low(info) -dminx: ds byte ;local for diskwrite -searchl: - ds byte ;search length -searcha: - ds word ;search address -tinfo: ds word ;temp for info in "make" -single: ds byte ;set true if single byte allocation map -resel: ds byte ;reselection flag -olddsk: ds byte ;disk on entry to bdos -fcbdsk: ds byte ;disk named in fcb -rcount: ds byte ;record count in current fcb -extval: ds byte ;extent number and extmsk -vrecord: - ds word ;current virtual record -arecord: - ds word ;current actual record -arecord1: - ds word ;current actual block# * blkmsk - -; local variables for directory access -dptr: ds byte ;directory pointer 0,1,2,3 -dcnt: ds word ;directory counter 0,1,...,dirmax -drec: ds word ;directory record 0,1,...,dirmax/4 - -;bios equ ($ and 0ff00h)+100h;next module - -;;dwg;; end - -;; dwg ; end dri source code here - -_bdos_end:: - .area _CODE - .area _CABS diff --git a/doug/src/dribdos.sym b/doug/src/dribdos.sym deleted file mode 100755 index 7e06663e..00000000 --- a/doug/src/dribdos.sym +++ /dev/null @@ -1,139 +0,0 @@ - ASxxxx Assembler V02.00 + NoICE + SDCC mods + Flat24 (Zilog Z80 / Hitachi HD64180), page 1. -'Bdos Interface, Bdos, Version 2.2 Feb, 1980' -Symbol Table - - .__.ABS.= 0000 G | 6 _bdos 0000 GR | 6 _bdos_en 0AC6 GR - 6 _bdos_st 0000 GR | 6 addh 03D1 R | addlist **** X - 6 alloca 0AC6 R | 6 allocate 030F R | 6 allocwd 0801 R - 6 arecord 0AC6 R | 6 arecord1 0AC6 R | 6 aret 01FC R - 6 atran 0315 R | 6 atran0 031B R | 6 backsp 0199 R - 6 backup 00D6 R | 6 backx 0158 R | 6 badseek 08E7 R - 6 bdose 0011 R | 6 blkmsk 0AC6 R | 6 blkshf 0AC6 R - 6 blockok 07E8 R | 6 buffa 0AC6 R | 6 buffnzer 06BE R - 6 cdrmaxa 0AC6 R | 6 check$ro 03BA R | 6 check$ro 03BD R - 6 check$wr 03C4 R | 6 checka 0AC6 R | 6 checksum 0402 R - 6 chksiz 0AC6 R | 6 close 0688 R | 6 clrmodnu 03DC R - 6 column 01FC R | 6 compcdr 03E5 R | 6 compcol 01FC R - 6 compext 0538 R | 6 compout 00AB R | 6 compute$ 0377 R - 6 compute$ 0902 R | 6 computec 037B R | 6 conb0 008D R - 6 conb1 0090 R | 6 conbrk 0074 R | 6 conech 0061 R - 6 conin 005B R | coninf **** X | 6 conout 0091 R - conoutf **** X | constf **** X | 6 copy$dir 0609 R - 6 copy$dir 0532 R | 6 copy$fcb 0609 R | cr **** X - 6 crlf 00F0 R | 6 crlfp 00DF R | 6 crlfp0 00E5 R - ctl **** X | ctlc **** X | ctle **** X - ctlh **** X | 6 ctlout 00BB R | ctlp **** X - ctlr **** X | ctls **** X | ctlu **** X - ctlx **** X | 6 curdsk 01FC R | 6 curreca 0AC6 R - 6 curselec 0984 R | 6 curtrka 0AC6 R | 6 dcnt 0AC6 R - 6 delete 05B1 R | 6 delete0 05B7 R | 6 diocomp 025A R - 6 dir$to$u 0445 R | 6 dirblk 0AC6 R | 6 dirinp 01D7 R - 6 dirloc 0AC6 R | 6 dirmax 0AC6 R | 6 diskeof 07A8 R - 6 diskread 0775 R | 6 diskwr0 07C3 R | 6 diskwr1 0807 R - 6 diskwr11 0850 R | 6 diskwr2 0862 R | 6 diskwr3 0885 R - 6 diskwrit 07AE R | 6 diskwru 0807 R | 6 dlog 0AC6 R - 6 dm$posit 02D5 R | 6 dmaad 0AC6 R | 6 dminx 0AC6 R - 6 dmpos0 02D9 R | 6 dmpos1 02E5 R | 6 dmpos2 02EE R - 6 dmset 06DA R | 6 dpbaddr 0AC6 R | dpblist **** X - 6 dptr 0AC6 R | 6 drec 0AC6 R | 6 dskerr 004A R - dskmap **** X | 6 dskmsg 004A R | dskmsk **** X - dskshf **** X | dvers **** X | 6 echoc 006F R - 6 efcb 0AC6 R | empty **** X | 6 end$of$d 044F R - enddir **** X | 6 endmerge 06EE R | 6 endsearc 059F R - 6 entsp 01FC R | 6 errflg 004A R | 6 extmsk 0AC6 R - extnum **** X | 6 extval 0AC6 R | false **** X - 6 fcb$copi 0AC6 R | 6 fcbdsk 0AC6 R | fcblen **** X - 6 fcbnzero 06B8 R | fcbshf **** X | 6 fill0 0825 R - 6 fill1 0831 R | 6 func$ret 01F8 R | 6 func1 01BF R - 6 func11 01F2 R | 6 func12 09B2 R | 6 func13 09B5 R - 6 func15 09C8 R | 6 func16 09D1 R | 6 func17 09D7 R - 6 func18 09EC R | 6 func19 09FB R | 6 func20 0A04 R - 6 func21 0A0A R | 6 func22 0A10 R | 6 func23 0A19 R - 6 func24 0A22 R | 6 func25 0A28 R | 6 func26 0A2E R - 6 func27 0A35 R | 6 func29 0A3B R | 6 func3 01C5 R - 6 func30 0A41 R | 6 func31 0A4A R | 6 func32 0A51 R - 6 func33 0A61 R | 6 func34 0A67 R | 6 func35 0A6D R - 6 func37 0A73 R | 6 func40 0AB9 R | 6 func6 01CB R - 6 func7 01E4 R | 6 func8 01EA R | 6 func9 01EC R - 6 functab 0037 R | fwfmsk **** X | 6 get$bloc 05CD R - 6 getalloc 0485 R | 6 getdm 02F0 R | 6 getdmd 02FE R - 6 getdptra 03CB R | 6 getexta 0331 R | 6 getfcb 033D R - 6 getfcba 0336 R | 6 getfiles 091F R | 6 getmodnu 03D6 R - 6 getnexts 094B R | 6 getsize 092C R | 6 goback 0A94 R - 6 goerr 01FC R | 6 hlrotl 0382 R | 6 hlrotl0 0383 R - 6 hlrotr 036A R | 6 hlrotr0 036B R | 6 home 0240 R - homef **** X | 6 index 0304 R | 6 indic0 063B R - 6 indicato 0638 R | 6 info 01FC R | 6 initial$ 0428 R - 6 initial0 04F0 R | 6 initial2 050B R | 6 initiali 04E4 R - ioloc **** X | 6 kbchar 01FC R | 6 lefttst 05CF R - lf **** X | 6 linelen 0173 R | 6 linfo 0AC6 R - 6 listcp 01FC R | listf **** X | lret **** X - 6 lstack 01FC R | lstrec **** X | 6 make 06F6 R - 6 make0 070E R | 6 maxall 0AC6 R | maxext **** X - maxmod **** X | 6 merge0 06AA R | 6 merged 06C5 R - 6 mergerr 06F4 R | 6 mergezer 067A R | modnum **** X - 6 move 0201 R | 6 move0 0202 R | namlen **** X - 6 newcheck 0402 R | nfuncs **** X | 6 nopblock 07DD R - 6 noselect 09A9 R | 6 nospace 0885 R | not **** X - 6 notbacks 00B9 R | 6 notc 01B6 R | 6 note 014A R - 6 noth 012D R | 6 notp 0154 R | 6 notr 01A3 R - 6 notrub 013B R | 6 notu 0170 R | 6 notx 0166 R - 6 noupdate 086D R | 6 nowrite 0399 R | nxtrec **** X - 6 offset 0AC6 R | 6 olddsk 0AC6 R | 6 open 0648 R - 6 open$cop 064F R | 6 open$mod 0740 R | 6 open$r$e 076C R - 6 open$rcn 0674 R | 6 open$ree 071F R | 6 open$ree 0746 R - 6 open$ree 0762 R | 6 open$ree 0765 R | 6 pctlh 00DC R - 6 pdollar 0529 R | 6 pererr 0009 R | 6 permsg 004A R - 6 persub 0037 R | 6 print 00F6 R | 6 qselect 09E6 R - 6 ranclose 08B6 R | 6 randiskr 08F4 R | 6 randiskw 08FB R - ranrec **** X | 6 rcount 0AC6 R | 6 rd$dir 0436 R - 6 rdbuff 0251 R | 6 rdech1 01A6 R | 6 rdecho 01A3 R - 6 read 0102 R | 6 read$dir 0459 R | 6 read$dir 046D R - 6 read$dir 0470 R | 6 readen 01BA R | readerf **** X - readf **** X | 6 readn0 0110 R | 6 readnx 010E R - reboot **** X | reccnt **** X | 6 recordok 0793 R - recsiz **** X | 6 rename 061C R | 6 rename0 0628 R - 6 rep0 017B R | 6 rep1 018D R | 6 resel 0AC6 R - 6 reselect 098D R | 6 retblock 05FB R | 6 retblock 0603 R - 6 retmon 0AAF R | 6 retselec 023E R | 6 righttst 05E0 R - 6 rmf 0AC6 R | 6 roderr 000D R | 6 rodmsg 004A R - 6 rodsk 0AC6 R | 6 rodsub 0041 R | 6 roferr 000F R - rofile **** X | 6 rofmsg 004A R | 6 rofsub 0044 R - 6 rotl 04A0 R | 6 rotr 04AC R | 6 rseek 0888 R - 6 rseek1 088C R | rubout **** X | 6 scandm 04B3 R - 6 scandm0 04B8 R | 6 scandm1 04C9 R | 6 scandm2 04CF R - 6 scanm3 04DE R | 6 search 0547 R | 6 search$f 05AB R - 6 searcha 0AC6 R | 6 searchex 058F R | 6 searchl 0AC6 R - 6 searchlo 0577 R | 6 searchn 0557 R | 6 searchne 0570 R - 6 searchok 0598 R | 6 sectpt 0AC6 R | sectran **** X - 6 seek 026B R | 6 seek$cop 0616 R | 6 seek$dir 025F R - 6 seek0 027B R | 6 seek1 0291 R | 6 seek2 02A6 R - 6 seekerr 08EC R | 6 seekok 08E2 R | 6 sel$erro 01FC R - seldskf **** X | 6 select 0960 R | 6 selectdi 020B R - 6 selerr 000B R | 6 selmsg 004A R | 6 selsub 003E R - 6 seqdiskr 0772 R | 6 seqdiskw 07AB R | 6 seqio 0AC6 R - 6 set$allo 04A6 R | 6 set$cdis 0389 R | 6 set$end$ 0455 R - 6 set$ro 03A5 R | 6 setcdr 03F2 R | 6 setdata 043C R - 6 setdir 043F R | 6 setdma 043F R | setdmaf **** X - 6 setfcb 0354 R | 6 setfcb1 035E R | 6 setfwf 03E0 R - 6 setlret1 01F9 R | 6 setrando 0953 R | setsecf **** X - 6 setsize 0951 R | settrkf **** X | 6 setusrco 0A5D R - 6 single 0AC6 R | 6 sta$ret 01F5 R | 6 sthl$ret 0A4D R - 6 strtcol 01FC R | 6 subdh 03FB R | tab **** X - 6 tab0 00CC R | 6 tabout 00C8 R | tbuff **** X - 6 tinfo 0AC6 R | 6 tranv 0AC6 R | true **** X - ubytes **** X | 6 usrcode 01FC R | 6 vrecord 0AC6 R - 6 wait$err 0044 R | 6 wrbuff 0257 R | 6 wrdir 042A R - writef **** X - ASxxxx Assembler V02.00 + NoICE + SDCC mods + Flat24 (Zilog Z80 / Hitachi HD64180), page 2. -'Bdos Interface, Bdos, Version 2.2 Feb, 1980' -Area Table - - 0 _CODE size 0 flags 0 - 1 _DATA size 0 flags 0 - 2 _OVERLAY size 0 flags 0 - 3 _HOME size 0 flags 0 - 4 _GSINIT size 0 flags 0 - 5 _GSFINAL size 0 flags 0 - 6 _BDOS size AC6 flags 0 - 7 _CABS size 0 flags 0 diff --git a/doug/src/dricbiosx.mac b/doug/src/dricbiosx.mac deleted file mode 100755 index d02d7f18..00000000 --- a/doug/src/dricbiosx.mac +++ /dev/null @@ -1,1400 +0,0 @@ -; ALTAIR 8800 BIOS with 8800 disk drives - 256 files each -; -; -; 02-May-2009, P. Schorn, removed DJNZ, bug found by Michael Rychlik -; 19-Apr-2009, P. Schorn, added automatic disk parameter block creation -; for disks with sector length 128 -; 15-Jan-2007, P. Schorn, added PSH and PHM in DPB for BIOS3 compatibility -; 05-Nov-2006, P. Schorn, configurable initial command after booting -; 14-Oct-2006, P. Schorn, made patching and Z80 check configurable -; 09-Oct-2002, P. Schorn, added support for simulated hard disk -; 01-Oct-2002, P. Schorn, changed computation for memory configuration (proposed -; by Scott LaBombard) -; 28-Apr-2002, P. Schorn, updated for new boot ROM -; 15-Apr-2002, P. Schorn, code clean up and simplification -; sanity check of (cdisk) to avoid loop on "Select" error -; 03-Apr-2002, P. Schorn, added CCP patches to allow SUBMIT -; on non-A boot drive as well -; moved lower case patch into BIOS -; 01-Apr-2002, P. Schorn, fixed bug in 'gotoit' -; 31-Mar-2002, P. Schorn, added BDOS patch to reboot in case of -; Bad Sector message and ^C typed -; 29-Mar-2002, P. Schorn, added symbol at end -; warm boot now uses the correct drive -; 23-Mar-2002, P. Schorn, added some CEO patches to BDOS - -false equ 0 -true equ not false - -initCmd equ false ; if true then cold boot invokes a command -sleepol equ true ; if true then sleep a bit while status polling - ; Note: requires SIMH - - .8080 -jpopcod equ (jmp) ; jp op-code -jpzopcd equ (jz) ; jp z op-code - - .Z80 - aseg - org 100h - maclib MEMCFG.LIB ; define configuration parameters - - .phase biosph -ccp equ ccpph ; ccp start address -bdos equ bdosph + 6 ; bdos start address -bios equ biosph ; bios start address - -; default values in case configuration parameters are left undefined - ifndef nhdisks -nhdisks equ 0 - endif - - ifndef needZ80 -needZ80 equ false - endif - - ifndef patchOS -patchOS equ false - endif - -wbotloc equ 0000h ; warm boot location -bdosloc equ 0005h ; BDOS entry location -bioserr equ 1 ; 1 indicates BIOS error -cdisk equ 0004h ; current disk location -ndisks equ 8 ; total number of Altair disks -tracks equ 254 ; number of tracks for regular drives -track1 equ tracks+1 ; indicator for unknown track position -asecsiz equ 137 ; sector size Altair -csecsiz equ 0080h ; sector size CP/M -rom equ 0ff00h ; address of Altair bootstrap loader in ROM -bootdr1 equ rom+0037h ; taken from dskboot (offset unitnooffset1) -bootdr2 equ rom+00b4h ; taken from dskboot (offset unitnooffset2) - -; Address Mode Function -; ------- ---- -------- -; selout Out Selects and enables controller and drive -; statin In Indicates status of drive and controller -; dskcon Out Controls disk function -; secpos In Indicates current sector position of disk -; dskwrit Out Write data -; dskread In Read data - -selout equ 8 ; port to select and enable controller and drive (OUT) -; +---+---+---+---+---+---+---+---+ -; | C | X | X | X | Device | -; +---+---+---+---+---+---+---+---+ -; -; C = If this bit is 1, the disk controller selected by 'device' is -; cleared. If the bit is zero, 'device' is selected as the -; device being controlled by subsequent I/O operations. -; X = not used -; Device = value zero thru 15, selects drive to be controlled. - -statin equ 8 ; port indicating status of drive and controller (IN) -; +---+---+---+---+---+---+---+---+ -; | R | Z | I | X | X | H | M | W | -; +---+---+---+---+---+---+---+---+ -; -; W - When 0, write circuit ready to write another byte. -; M - When 0, head movement is allowed -; H - When 0, indicates head is loaded for read/write -; X - not used (will be 0) -; I - When 0, indicates interrupts enabled (not used this simulator) -; Z - When 0, indicates head is on track 0 -; R - When 0, indicates that read circuit has new byte to read - -dskcon equ 9 ; port to control disc function (OUT) -; +---+---+---+---+---+---+---+---+ -; | W | C | D | E | U | H | O | I | -; +---+---+---+---+---+---+---+---+ -; -; I - When 1, steps head IN one track -; O - When 1, steps head OUT one track -; H - When 1, loads head to drive surface -; U - When 1, unloads head -; E - Enables interrupts (ignored by this simulator) -; D - Disables interrupts (ignored by this simulator) -; C - When 1 lowers head current (ignored by this simulator) -; W - When 1, starts Write Enable sequence: -; W bit on device 'statin' (see above) will go 1 and data will be read from -; port 'dskread' until 137 bytes have been read by the controller from -; that port. The W bit will go off then, and the sector data will be written -; to disk. Before you do this, you must have stepped the track to the desired -; number, and waited until the right sector number is presented on -; device 'secpos', then set this bit. - -secpos equ 9 ; port to indicate current sector position of disk (IN) -; As the sectors pass by the read head, they are counted and the -; number of the current one is available in this register. -; -; +---+---+---+---+---+---+---+---+ -; | X | X | Sector Number | T | -; +---+---+---+---+---+---+---+---+ -; -; X = Not used -; Sector number = binary of the sector number currently under the head, 0-31. -; T = Sector True, is a 1 when the sector is positioned to read or write. - -dskwrit equ 10 ; port to write data (OUT) -dskread equ 10 ; port to read data (IN) - -; All I/O is via programmed I/O. Each device has a status port -; and a data port. A write to the status port can select -; some options for the device although the simulator only -; recognizes the reset command (0x03). -; A read of the status port gets the port status: -; -; +---+---+---+---+---+---+---+---+ -; | X | X | X | X | X | X | O | I | -; +---+---+---+---+---+---+---+---+ -; -; I - A 1 in this bit position means a character has been received -; on the data port and is ready to be read. -; O - A 1 in this bit means the port is ready to receive a character -; on the data port and transmit it out over the serial line. -; -; A read to the data port gets the buffered character, a write -; to the data port writes the character to the device. -constat equ 16 ; sio port 1 status port -condata equ 17 ; sio port 1 data port -punstat equ 18 ; sio port 2 status port -pundata equ 19 ; sio port 2 data port - -; masks for disk controller (statin) -mhm equ 02h ; head movement mask -mtzero equ 40h ; head on track zero mask -mall equ 0ffh ; everything ok mask - -; commands for disk controller (dskcon) -cstepin equ 01h ; step in command -cstepot equ 02h ; step out command -cload equ 04h ; load head to drive surface command -cuload equ 08h ; unload head from drive surface command -cwrseq equ 80h ; 'start write enable sequence' command - -; masks for SIO controller (constat, punstat) -mout equ 02h ; output allowed mask - -; commands for SIO controller (constat, punstat) -creset equ 3 ; reset command - - if nhdisks gt 0 -; constants for hard disk port -hdskReset equ 1 ; command to reset controller -hdskRead equ 2 ; read command -hdskWrite equ 3 ; write command -hdskParam equ 4 ; param command -hdskport equ 0fdh ; control port for simulated hard disk -firstSector equ 17 ; first sector to load -firstTrack equ 0 ; from this track -firstDiskAddr equ 256*firstTrack+firstSector -sectors equ (ccplen+bdoslen)/csecsiz - endif - -dirent equ 255 ; number of directory entries -restrk equ 6 ; reserved tracks -dsm06 equ 1efh ; maximum data block number for disks 0 to 6 -dsm07 equ 254 ; maximum data block number for disk 7 -spt equ 32 ; sectors per track -sptmask equ spt-1 ; mask corresponding to 'spt' -cks equ (dirent+1)/4 -cr equ 13 ; Carriage Return -lf equ 10 ; Line Feed - - jp boot ; cold start -wboote: jp wboot ; warm start (reboot) - jp const ; console status - jp conin ; console input - jp conout ; console output - jp list ; list character out - jp punch ; punch character out - jp reader ; read character in - jp home ; move disk head to home - jp seldsk ; select disk drive - jp settrk ; set track number - jp setsec ; set sector number - jp setdma ; set disk memory read/write address - jp read ; read sector - jp write ; write sector - jp listst ; list dev status test - jp sectrn ; sector translate - -; The BOOT entry point gets control from the cold start loader and is -; responsible for basic system initialization, including sending a sign-on -; message, which can be omitted in the first version. If the IOBYTE function -; is implemented, it must be set at this point. The various system parameters -; that are set by the WBOOT entry point must be initialized, and control is -; transferred to the CCP at 3400 + b for further processing. Note that -; register C must be set to zero to select drive A. -boot: ld sp,chk02 - ld a,(bootdr1) ; load current disk with boot drive - ld (cdisk),a - ld de,msg1 ; print welcome message - call msg - - if needZ80 -entcpm: xor a - dec a - jp po,ent2 ; all eight bits set means parity even for 8080, po is Z80 - ld de,msg2 ; got an 8080 which is no good - call msg ; warn user - halt ; wait for processor to be changed - jp entcpm ; and try again -ent2 equ $ - else -entcpm equ $ - endif - - ld a,jpopcod ; jp instruction code - ld (wbotloc),a ; store at entry to warm boot - ld hl,wboote ; get jump location - ld (wbotloc+1),hl ; and store it after jp instruction - ld (bdosloc),a ; jp instruction code for entry to BDOS - ld hl,bdos ; get jump location - ld (bdosloc+1),hl ; and store it after jp instruction - - if patchOS -; begin patch CCP and BDOS - ld b,low ((patche-patchs) shr 2) ; number of entries in patch table - ld hl,patchs ; start of patch table -patch1: ld e,(hl) ; is lower byte of address for jp instruction - inc hl ; point to upper byte - ld d,(hl) ; points to address for jp instruction - inc hl ; points to lower byte of source jp address - ld a,jpopcod ; jp op code - ld (de),a ; store jp op-code to appropriate location - inc de ; points to lower byte of destination jp address - ld a,(hl) ; get lower byte of address - ld (de),a ; store it - inc hl ; point to upper byte source jp address - inc de ; point to upper byte destination jp address - ld a,(hl) ; get upper byte of address - ld (de),a ; store it - inc hl ; point to next table pair - dec b ; entry done - jp nz,patch1 ; if more to do - -; patch bdos to perform a ROM reboot in case of Bad Sector error -; is detected and user has typed ^C. This is to make sure that one -; can recover from errors due to non-existing drives. - ld hl,rom - ld (bdos+009ch),hl ; at bdos+9bh we now have jp z,rom instead of jp z,0 - -; patch ccp to look on ipl drive if file not found - ld a,jpzopcd ; replace jp opcode with jp z opcode - ld (ccp+06dbh),a ; plug into ccp at intercept point - - ld hl,lctabs - ld c,low ((lctabe-lctabs) / 3) ; number of table entries -;precondition: points to table with structure (byte length, word address)* -;at 'address' starts a character string of length 'length' which is to be translated to -;lower case -tolc: ld b,(hl) ; points to length byte - inc hl ; points to lower byte of address - ld e,(hl) ; E := lower byte of address - inc hl ; points to upper byte of address - ld d,(hl) ; D := upper byte of address - inc hl ; points to next length byte - ex de,hl -tolc1: ld a,(hl) ; get character to be transformed - cp 'A' - jp c,tolc2 ; next character if less than 'A' - cp 'Z'+1 - jp nc,tolc2 ; next character if greater than 'Z' - add a,'a'-'A' ; to lower case - ld (hl),a ; store back -tolc2: inc hl ; point to next character - dec b ; count down length - jp nz,tolc1 ; repeat if necessary - ex de,hl ; points to next length byte - dec c ; update number of table entries processed - jp nz,tolc ; if not equal to zero, continue -;end patch CCP and BDOS - endif - - - if initCmd - ld de,ccp+7 ; destination in CCP - ld hl,cmdBeg ; command length, command, 0 -movCmd: ld a,(hl) ; get byte - ld (de),a ; store at destination - or a ; check byte - jp z,doneMv ; zero byte is the last, done - inc hl ; next source - inc de ; next destination - jp movCmd ; repeat -doneMv: ld (cmdBeg),a ; execute only once - endif - - ld a,creset ; reset command - out (constat),a ; reset console device - out (punstat),a ; and list/punch device - ld bc,0080h - call setdma - ld a,(cdisk) ; get current disk - cp ndisks+nhdisks ; does it exist? - jp c,ent1 ; yes, proceed - ld a,(bootdr1) ; get boot drive - ld (cdisk),a ; and make it current disk -ent1: ld c,a ; inform CCP - ei - jp ccp - - if initCmd -cmdBeg: db cmdEnd-cmdBeg-2,'DO INITMAKE',0 -cmdEnd equ $ - endif - - - if patchOS -; DD40 3A E3EF ld a,(cdisk) -; DD43 B7 or a -; DD44 3E 00 ld a,0 -; DD46 C4 DCBD call nz,select -; DD49 11 E3AC ld de,subfcb -;DD43: jp ccpp1 -ccpp1: ld e,a ; := current disk - ld a,(bootdr1) ; := boot drive - cp e ; compare boot drive with current disk - jp ccp+0146h ; a select of boot drive occurs iff current disk <> boot drive - -; DD7D 3A E3EF ld a,(cdisk) -; DD80 B7 or a -; DD81 C4 DCBD call nz,select -; DD84 21 DC08 ld hl,combuf -;DD7D: jp ccpp2 -ccpp2: ld a,(bootdr1) ; := boot drive - ld e,a ; := boot drive - ld a,(ccp+07efh) ; := current disk - cp e ; compare boot drive with current disk - jp ccp+0181h ; a select of current disk occurs iff current disk <> boot drive - -; DDE3 36 00 ld (hl),0 ;submit flag is set to false -; DDE5 AF xor a -; DDE6 CD DCBD call select ;on drive a to erase file -; DDE9 11 E3AC ld de,subfcb -;DDE3: jp ccpp3 -ccpp3: ld (hl),0 ; patched over - ld a,(bootdr1) ; := boot drive - jp ccp+01e6h ; go select boot drive - -; patch bdos to change the drive selected by -; BDOS Function 13 (Reset Disk System). -f13pat: ld a,(bootdr1) ; get boot drive - ld (bdos+033ch),a ; store into curdsk (BDOS) - jp bdos+0c8ah - -; patch ccp to look on ipl drive if file not found -ccpat: ld hl,ccp+07f0h ; look at drive spec in command - or (hl) ; zero means default was taken - jp nz,ccp+076bh ; if nonzero don't change it - ld a,(bootdr1) ; take boot drive and increment it since - inc a ; for a FCB A=1, B=2, ... - ld (hl),a ; modify command line - ld de,ccp+07d6h ; setup for retry - jp ccp+06cdh ; go retry command - -; patch ccp to show current user number in prompt -propat: call ccp+0113h ; get current user no - or a - jp z,prono ; do not show it if it's 0 - cp 10 ; see if 1 or 2 digits - jp nc,pro2 - add a,'0' -pro1: call ccp+008ch ; output a character -prono: ld a,'>' ; prompt character - call ccp+008ch ; output it - jp ccp+0395h ; resume ! -pro2: add a,'0' - 10 - push af - ld a,'1' - call ccp+008ch - pop af - jp pro1 - -; patch bdos to look at user 0 if file not found in current user # -pubpat: ld a,b ; get char count - or a ; looking at first byte? - jp nz,pubno ; no, skipit - ld a,(de) ; get user # from directory - cp 0e5h ; active dir entry? - jp z,pubno ; no - ld a,(hl) ; get user# from dir entry - or a ; is it user # 0? - jp z,bdos+0776h ; yes, force char match regardless -pubno: ld a,b - cp 13 - jp bdos+075bh - endif - -; print the message pointed to by and terminated by '$' to the console -; leaves unchanged -msg: ld a,(de) ; get character - cp '$' ; is is the terminating character? - ret z ; yes, we are done - ld c,a ; 'conout' expects the character in - call conout ; disply it on console - inc de ; point to next character - jp msg ; and repeat - -; The WBOOT entry point gets control when a warm start occurs. A warm -; start is performed whenever a user program branches to location 0000H, or -; when the CPU is reset from the front panel. The CP/M system must be -; loaded from the first two tracks of drive A up to, but not including, the -; BIOS, or CBIOS, if the user has completed the patch. System parameters -; must be initialized as follows: -; location 0,1,2 Set to JMP WBOOT for warm starts -; (000H: JMP 4A03H + b) -; location 3 Set initial value of IOBYTE, if implemented in the -; CBIOS -; location 4 High nibble = current user no; low nibble current -; drive -; location 5,6,7 Set to JMP BDOS, which is the primary entry point -; to CP/M for transient programs. (0005H: JMP 3C06H + b) -; Upon completion of the initialization, the WBOOT program must branch to the -; CCP at 3400H + b to restart the system. Upon entry to the CCP, register C -; is set to the drive to select after system initialization. The WBOOT -; routine should read location 4 in memory, verify that is a legal drive, and -; pass it to the CCP in register C. -wboot: ld sp,chk02 - ld a,(bootdr1) ; make sure that ccp and bdos are loaded from correct disk - - if nhdisks gt 0 - cp ndisks - jp c,altdsk - ld b,32 ; reset hard disk controller - ld a,hdskReset ; by issuing the reset command 32 times -rhdsk: out (hdskPort),a - dec b - jp nz,rhdsk ; post condition is := 0 - ld de,firstDiskAddr ; := 0 (Track), := 8 (Sector) - ld hl,ccp ; DMA address - ld c,sectors ; is loop counter -again: ld a,hdskRead - out (hdskport),a ; send read command to hard disk port - ld a,(bootdr1) ; in real life take disk number from boot ROM - sub ndisks ; correct for Altair disks - out (hdskport),a ; send drive to boot from to hard disk port - ld a,e - out (hdskport),a ; send sector - ld a,d - out (hdskport),a ; send lower byte of track - xor a - out (hdskport),a ; send higher byte of track which is always 0 - ld a,l - out (hdskport),a ; send lower byte of DMA address - ld a,h - out (hdskport),a ; send upper byte of DMA address - in a,(hdskport) ; perform operation and get result - or a - jp z,cont ; continue if no error - halt ; halt otherwise -cont: ld a,c ; save in - ld c,csecsiz ; is now 128 since always zero - add hl,bc ; get next DMA address - ld c,a ; restore from - dec c ; decrement loop counter - jp z,entcpm - inc e ; Sector := Sector + 2 - inc e - ld a,e - cp spt ; is new Sector equal to 32 - jp z,switch ; yes, need to go to odd sectors - cp spt+1 ; is new Sector equal to 33 - jp nz,again ; no, proceed with read - ld e,0 ; Sector := 0 - inc d ; Track := Track + 1 - jp again ; proceed with read -switch: ld e,1 ; Sector := 1 - jp again ; proceed with read -altdsk equ $ - endif - - out (selout),a ; select it - ld a,cload ; load head command - out (dskcon),a ; load head to drive surface - call dhome ; position disk head on track zero - ld de,ccp ; destination load address - ld b,17 ; first sector to read on track zero -nextsc: push bc ; save current sector to read, is undefined - push de ; save current destination load address - call seclp2 ; position to sector in - call blread ; read the sector - pop de ; restore current destination load address, is destination - ld hl,altbuf+3 ; ignore first three byte of buffer, is source - call ldir ; has been set by 'blread' - pop bc ; is current sector, is undefined - ld hl,bios ; when reaches this address we are done - ld a,d - cp h - jp nz,decide - ld a,e - cp l -decide: jp nc,gotoit ; jump if everything loaded - inc b ; compute next sector number - inc b - ld a,b - cp spt ; compare new sector number with sectors per track - jp c,nextsc ; continue if less - ld b,1 ; otherwise prepare for odd numbered sectors - jp z,nextsc ; if old sector number was equal to sectors per track - call whmove ; loop until head movement is allowed - ld a,cstepin ; step in one track command - out (dskcon),a ; step in one track - ld b,0 ; start with even sectors - jp nextsc -gotoit: ld a,(bootdr2) ; clear disk controller of correct disk - out (selout),a ; do it - ld hl,ontrk0 ; start address of table for current track positions - ld b,ndisks ; number of disks -resett: ld (hl),track1 ; reset entry for disk - inc hl ; point to next entry - dec b ; decrement counter for disks to go - jp nz,resett ; jump if not yet done - jp entcpm - -; You should sample the status of the currently assigned console device and -; return 0FFH in register A if a character is ready to read and 00H in register -; A if no console characters are ready. -; -; console in/out routines - use sio port 1 -; -const: in a,(constat) ; get console status - rra ; I bit into carry - ld a,0 ; prepare no character available - ret nc ; I bit clear means no character, done - dec a ; character available, result is 0ffh - ret ; done - -; The next console character is read into register A, and the parity bit is set, -; high-order bit, to zero. If no console character is ready, wait until a -; character is typed before returning. - if sleepol - -conin: in a,(constat) ; get console status - rra ; I bit into carry - jp c,getchr ; get character - ld a,27 ; otherwise sleep for SIMHSleep microseconds - out (0feh),a ; execute command - jp conin ; try again -getchr: in a,(condata) ; read character - and 7fh ; clear bit 8 - ret - - else - -conin: in a,(constat) ; get console status - rra ; I bit into carry - jp nc,conin ; jump back if no character available - in a,(condata) ; read character - and 7fh ; clear bit 8 - ret - - endif - -; The character is sent from register C to the console output device. The -; character is in ASCII, with high-order parity bit set to zero. You might -; want to include a time-out on a line-feed or carriage return, if the console -; device requires some time interval at the end of the line (such as a TI Silent -; 700 terminal). You can filter out control characters that cause the console -; device to react in a strange way (CTRL-Z causes the Lear-Siegler terminal -; to clear the screen, for example). -conout: in a,(constat) ; get console status - and mout ; mask output bit - jp z,conout ; jump back if not ready for output - ld a,c ; prepare character for output - out (condata),a ; do it - ret - -; -; reader/punch routines use sio port 2 -; -; The character is sent from register C to the currently assigned listing -; device. The character is in ASCII with zero parity bit. -list: ; list aliased to punch -; The character is sent from register C to the currently assigned punch -; device. The character is in ASCII with zero parity. -punch: in a,(punstat) ; get punch status - and mout ; mask output bit - jp z,punch ; jump back if not ready for output - ld a,c ; prepare character for output - out (pundata),a ; do it - ret - -; The next character is read from the currently assigned reader device into -; register A with zero parity (high-order bit must be zero); an end-of-file -; condition is reported by returning an ASCII CTRL-Z(1AH). -reader: in a,(punstat) ; get reader status - rra ; I bit into carry - jp nc,reader ; jump back if no character available - in a,(pundata) ; read character - ret - -; The disk drive given by register C is selected for further operations, where -; register C contains 0 for drive A, 1 for drive B, and so on up to 15 for -; drive P (the standard CP/M distribution version supports four drives). On -; each disk select, SELDSK must return in HL the base address of a 16-byte -; area, called the Disk Parameter Header, described in Section 6.10. For -; standard floppy disk drives, the contents of the header and associated -; tables do not change; thus, the program segment included in the sample -; CBIOS performs this operation automatically. -; If there is an attempt to select a nonexistent drive, SELDSK returns HL = -; 0000H as an error indicator. Although SELDSK must return the header -; address on each call, it is advisable to postpone the physical disk select -; operation until an I/O function (seek, read, or write) is actually performed, -; because disk selects often occur without ultimately performing any disk -; I/O, , and many controllers unload the head of the current disk before -; selecting the new drive. This causes an excessive amount of noise and disk -; wear. The least significant bit of register E is zero if this is the first -; occurrence of the drive select since the last cold or warm start. -seldsk: ld hl,0 ; select disk number - ld a,c - ld (diskno),a - cp ndisks+nhdisks ; number of disk drives - ret nc ; error - disk number too high - ld l,a ; := disk number - ld h,0 - add hl,hl ; disk number * 2 - add hl,hl ; disk number * 4 - add hl,hl ; disk number * 8 - add hl,hl ; disk number * 16 - ld de,dpbase ; dpbase entries have size of 16 bytes - add hl,de ; = 16 * disknumber + dpbase - - if nhdisks gt 0 - ld a,(diskno) - cp ndisks ; is it a hard disk? - ret c ; no - push hl ; Preserve pointer to disk descriptor - ld bc,10 ; offset to disk parameter block address - add hl,bc - ld a,(hl) - inc hl - ld h,(hl) - ld l,a ; point at disk dpb - push hl ; save this pointer - ld a,hdskParam - out (hdskPort),a ; send 'get parameters' command - ld a,(diskno) - sub ndisks - out (hdskPort),a ; send selected HDSK number - ld b,17 -hdskpl: in a,(hdskPort) ; read 17-bytes of DPB - ld (hl), a - inc hl - dec b - jp nz,hdskpl - in a,(hdskPort) ; read LSB of disk's physical sector size. - cp 128 ; is it 128? - jp nz,secnok1 ; no, fail - in a,(hdskPort) ; read MSB of disk's physical sector size. - or a ; is it 0? - jp nz,secnok2 ; no, sector size is not 128, fail - pop hl ; restore disk parameter block - ld bc,11 ; offset to CKS - add hl,bc ; points to CKS - ld a,(hl) ; get lower byte - inc hl - or (hl) ; or with higher byte - jp z,secok ; success if zero - ld de,secmsg3 ; otherwise not a hard disk - jp prmsg ; print error message -secok: pop hl ; restore pointer to disk descriptor - ret -secnok1: - in a,(hdskPort) ; get and drop MSB -secnok2: - ld de,secmsg2 ; physical sector is not 128 -prmsg: call msg ; print error message - halt - jp rom -secmsg2: - db cr, lf, 'Physical sector size must be 128 bytes.', cr, lf, '$' - -secmsg3: - db cr, lf, 'Must be a hard disk.', cr, lf, '$' - - else - ret - endif - -; The disk head of the currently selected disk (initially disk A) is moved to -; the track 00 position. If the controller allows access to the track 0 flag -; from the drive, the head is stepped until the track 0 flag is detected. If the -; controller does not support this feature, the HOME call is translated into a -; call to SETTRK with a parameter of 0. -home: ld bc,0 ; move to track 00 - ; fall into settrk - -; Register BC contains the track number for subsequent disk accesses on the -; currently selected drive. The sector number in BC is the same as the -; number returned from the SECTRAN entry point. You can choose to seek -; the selected track at this time or delay the seek until the next read or write -; actually occurs. Register BC can take on values in the range 0-76 -; corresponding to valid track numbers for standard floppy disk drives and -; 0-65535 for nonstandard disk subsystems. -settrk: ld l,c ; save track - ld h,b - ld (track),hl - ret - -; Register BC contains the sector number, 1 through 26, for subsequent disk -; accesses on the currently selected drive. The sector number in BC is the -; same as the number returned from the SECTRAN entry point. You can -; choose to send this information to the controller at this point or delay -; sector selection until a read or write operation occurs. -setsec: ld a,c ; set sector - ld (sector),a - ret - -; Logical-to-physical sector translation is performed to improve the overall -; response of CP/M. Standard CP/M systems are shipped with a skew factor -; of 6, where six physical sectors are skipped between each logical read -; operation. This skew factor allows enough time between sectors for most -; programs to load their buffers without missing the next sector. In particular -; computer systems that use fast processors, memory, and disk subsystems, -; the skew factor might be changed to improve overall response. However, -; the user should maintain a single-density IBM-compatible version of CP/M -; for information transfer into and out of the computer system, using a skew -; factor of 6. -; In general, SECTRAN receives a logical sector number relative to zero in -; BC and a translate table address in DE. The sector number is used as an -; index into the translate table, with the resulting physical sector number in -; HL. For standard systems, the table and indexing code is provided in the -; CBIOS and need not be changed. -sectrn: - if nhdisks gt 0 - ld l,c ; := BC, prepration for = 0 - ld h,b ; load upper byte - inc hl ; rebase to one - ld a,e ; get lower byte of translate table address - or d ; or with upper byte - ret z ; if equal to zero, no translation necessary - endif - ex de,hl ; := translate table address - add hl,bc ; add sector number - ld l,(hl) ; get pointed to byte - ld h,0 ; set upper byte to zero - ret ; done - -; Register BC contains the DMA (Disk Memory Access) address for -; subsequent read or write operations. For example, if B = 00H and C = 80H -; when SETDMA is called, all subsequent read operations read their data -; into 80H through 0FFH and all subsequent write operations get their data -; from 80H through 0FFH, until the next call to SETDMA occurs. The initial -; DMA address is assumed to be 80H. The controller need not actually -; support Direct Memory Access. If, for example, all data transfers are -; through I/O ports, the CBIOS that is constructed uses the 128byte area -; starting at the selected DMA address for the memory buffer during the -; subsequent read or write operations. -setdma: ld l,c ; set dma address - ld h,b - ld (dmaad),hl - ret - -; -; altair disk read/write drivers -; -; Assuming the drive has been selected, the track has been set, and -; the DMA address has been specified, the READ subroutine attempts to -; read eone sector based upon these parameters and returns the following -; error codes in register A: -; -; 0 no errors occurred -; -; 1 nonrecoverable error condition occurred -; -; Currently, CP/M responds only to a zero or nonzero value as the return -; code. That is, if the value in register A is 0, CP/M assumes that the disk -; operation was completed properly. IF an error occurs the CBIOS should -; attempt at least 10 retries to see if the error is recoverable. When an error -; is reported the BDOS prints the message BDOS ERR ON x: BAD -; SECTOR. The operator then has the option of pressing a carriage return to -; ignore the error, or CTRL-C to abort. - if nhdisks gt 0 -read: ld a,(diskno) ; get disk number - cp ndisks ; compare with number of Altair disks - jp c,aread ; carry means we got an Altair disk - ld a,hdskRead ; otherwise perform hard disk read - jp shdpar ; send hard disk parameters -aread equ $ - else -read equ $ - endif - call poshed ; select disk 'diskno' and position disk head to 'track' - call secget ; position head to desired sector - di - call blread - ld a,cuload ; unload head command - out (dskcon),a ; do it - ei - ld de,altbuf+3 ; address of sector just read - ld hl,(dmaad) ; destination address - ex de,hl ; prepare for ldir - call ldir ; move - -; You return the ready status of the list device used by the DESPOOL -; program to improve console response during its operation. The value 00 is -; returned in A if the list device is not ready to accept a character and 0FFH -; if a character can be sent to the printer. A 00 value should be returned if -; LIST status is not implemented. -listst: xor a ; := 0 means no error - ret - -; Data is written from the currently selected DMA address to the currently -; selected drive, track, and sector. For floppy disks, the data should be -; marked as nondeleted data to maintain compatibility with other CP/M -; systems. The error codes given in the READ command are returned in -; register A, with error recovery attempts as described above. - if nhdisks gt 0 -write: ld a,(diskno) ; get disk number - cp ndisks ; compare with number of Altair disks - jp c,awrite ; carry means we got an Altair disk - ld a,hdskWrite ; otherwise perform hard disk write -shdpar: out (hdskPort),a ; send command - ld a,(diskno) ; get disk number - sub ndisks ; rebase - out (hdskPort),a ; send rebased disk number - ld a,(sector) ; get sector - dec a ; rebase to 0 - out (hdskPort),a ; send rebased sector number - ld a,(track) ; get lower byte of track - out (hdskPort),a ; send lower byte of track - ld a,(track+1) ; get upper byte of track - out (hdskPort),a ; send upper byte of track - ld a,(dmaad) ; get lower byte DMA address - out (hdskPort),a ; send lower byte of DMA address - ld a,(dmaad+1) ; get upper byte of DMA address - out (hdskPort),a ; send upper byte of DMA address - in a,(hdskPort) ; perform command and get result - ret -awrite equ $ - else -write equ $ - endif - call poshed ; select desired disk and position to desired track - call secget ; position head to desired sector - ld hl,(dmaad) ; source of sector is in 'dmaad' - ld de,altbuf+3 ; destination inside local buffer - ld bc,csecsiz ; sector size is 128 - call ldir ; block move - ld a,cwrseq ; command for 'start write enable sequence' - out (dskcon),a ; do it - di - ld hl,altbuf ; point to first byte in local buffer - ld b,asecsiz+1 ; number of bytes to write (additional byte triggers 'real' write) -wready: in a,(statin) ; get status - rra ; get bit for ready for write - jp c,wready ; loop until ready for write - ld a,(hl) ; byte to write - out (dskwrit),a ; write byte - inc hl ; point to next byte - dec b ; decrement counter of bytes - jp nz,wready ; jp if not done - ld a,cuload ; unload head command - out (dskcon),a ; do it - ei - xor a ; := 0 means no error - ret - -; Postcondition: 'altbuf' contains 'asecsiz' many bytes, is set to 'csecsiz' -blread: ld hl,altbuf ; address of sector buffer - ld e,asecsiz ; number of bytes to read -blrd1: in a,(statin) ; get disk status - or a ; set sign of byte - jp m,blrd1 ; loop until disk has new byte to read - in a,(dskread) ; read byte of sector - ld (hl),a ; store into buffer - inc hl ; point to next position in buffer - dec e ; decrement size counter - jp nz,blrd1 ; if not zero, we need to continue - ld bc,csecsiz ; sector size in preparation for call to 'ldir' - ret - -; position disk on track zero, == 0 at the end -dhome: in a,(statin) ; position disk to track 0 - and mtzero ; mask for 'head is on track zero' - ret z ; track zero reached, done - call whmove ; loop until head movement is allowed - ld a,cstepot ; command for 'step head out one track' - out (dskcon),a ; do it - jp dhome ; try again - -; Select disk 'diskno' and position disk head to 'track' -poshed: call calcd ; position altair disk head - ld a,d ; select disk , cur track in - out (selout),a ; select disk - in a,(statin) ; get status of selected drive - cp mall ; ok? - jp z,selerr ; no! - ld a,b ; := track of selected disk - cp track1 ; compare with non-existing track - jp nz,alseek ; if a regular track, proceed to seek - call dhome ; position disk to track 0 - ld b,a ; := 0 (current track) -;Input: location 'track' contains desired track -; contains current track -;Output: desired track is reached and stored in track array -alseek: ld a,(track) ; seek to 'track' (cur track in b) - ld e,a ; := desired track - ld a,b ; := current track - sub e ; := current track - desired track - ret z ; we are already at desired track - ld e,a ; e is the number of "step in" or "step out" - jp c,stpin ; current track < desired track - ld c,cstepot ; command for step head out one track - jp aseek ; perform steps -stpin: ld c,cstepin ; command for step head in one track - cpl ; := ~(current track - desired track) - inc a ; := desired track - current track (positive) - ld e,a ; is positive number of tracks to move -aseek: call whmove ; loop until head movement is allowed - ld a,c ; get command (step in or step out) - out (dskcon),a ; perform it - dec e ; next iteration - jp nz,aseek ; loop if not done - call calcd ; get pointer to 'track' of 'diskno' - ld a,(track) ; this is the current track - ld (hl),a ; update 'track' of 'diskno' - ret -selerr: pop hl ; discard return address - ld a,bioserr ; := 1 means error - ret - -; loop until head movement is allowed -whmove: in a,(statin) ; get status - and mhm ; mask for 'head movement allowed' - jp nz,whmove ; loop until movement allowed - ret - -; Input: - implicit input is location 'diskno' -; Output: contains the current track of 'diskno' -; , and contain 'diskno' -; points to 'track' of 'diskno' -calcd: ld a,(diskno) ; get 'diskno' - ld e,a ; := 'diskno' - ld hl,ontrk0 - ld d,0 - add hl,de ; points to 'track' of 'diskno' - ld b,(hl) ; := 'track' of 'diskno' - ld d,e ; := 'diskno' - ret - -; Input: 'sector' contains desired sector number -; Output: head is positioned at desired sector -secget: ld a,cload ; command to load head to drive surface - out (dskcon),a ; do it - ld a,(sector) ; := desired sector - dec a ; adjust to range 0..(spt-1) - ld b,a ; := adjusted, desired sector - cp spt ; compare with sectors per track - jp c,seclp2 ; desired sector is less than total sectors per track, ok - ld de,secmsg ; prepare error message - call msg ; print it - halt ; not much we can do -seclp2: in a,(secpos) ; get sector position - rra ; rotate T bit into carry - jp c,seclp2 ; loop until sector is positioned to read or write - and sptmask ; now contains the sector under the head - cp b ; compare with desired sector - jp nz,seclp2 ; repeat if not equal - ret - -; Move bytes from start address to destination . -; This is equivalent to the Z80 instruction 'LDIR'. -; This subroutine dynamically determines the processor. -ldir: xor a ; := 0 - dec a ; := 1111'1111b - jp pe,ldir1 ; on an 8080 this means parity is even - ldir ; otherwise we have a Z80 - ret -ldir1: ld a,(hl) ; get byte from source - ld (de),a ; put byte to destination - inc hl ; point to next source address - inc de ; point to next destination address - dec bc ; decrement number of bytes to move - ld a,c ; := ( or ) - or b - jp nz,ldir1 ; not zero, move again - ret - - if patchOS -lctabs: db 9 ; (R)EAD ERROR - dw ccp+03e0h ; DFE0 - db 6 ; (N)O FILE - dw ccp+03f1h ; DFF1 - db 2 ; (A)LL - dw ccp+0553h ; E153 - db 7 ; (N)O SPACE - dw ccp+0608h ; E208 - db 10 ; (F)ILE EXISTS - dw ccp+0683h ; E283 - db 7 ; (B)AD LOAD - dw ccp+077bh ; E37B -lctabe equ $ - -patchs: dw ccp+0143h, ccpp1 ; DD43: jp ccpp1 - dw ccp+017dh, ccpp2 ; DD7D: jp ccpp2 - dw ccp+01e3h, ccpp3 ; DDE3: jp ccpp3 - dw ccp+0392h, propat - dw ccp+06dbh, ccpat - dw bdos+0c86h, f13pat - dw bdos+0758h, pubpat -patche equ $ - endif - -; In general, each disk drive has an associated (16-byte) disk parameter -; header that contains information about the disk drive and provides a -; scratch pad area for certain BDOS operations. The format of the disk -; parameter header for each drive is shown below, where each element is a -; word (16-bit) value. -; -; DISK PARAMETER HEADER -; +-------+------+------+------+----------+-------+-------+-------+ -; | XLT | 0000 | 0000 | 0000 |DIRBUF| DPB | CSV | ALV | -; +------+------+------+-------+----------+-------+-------+-------+ -; 16B 16B 16B 16B 16B 16B 16B 16B -; -; XLT Address of the logical-to-physical translation vector, if used -; for this particular drive, or the value 0000H if no sector translation -; takes place (that is, the physical and logical sector numbers are the -; same). Disk drives with identical sector skew factors share the same -; translate tables. -; -; 0000 Scratch pad values for use within the BDOS, initial value is -; unimportant. DIRBUF Address of a 128-byte scratch pad area for directory -; operations within BDOS. All DPHs address the same scratch pad area. -; -; DPB Address of a disk parameter block for this drive. Drives -; withidentical disk characteristics address the same disk parameter block. -; -; CSV Address of a scratch pad area used for software check for -; changed disks. This address is different for each DPH. -; -; ALV Address of a scratch pad area used by the BDOS to keep disk -; storage allocation information. This address is different for each DPH. -; -; Given n disk drives, the DPHs are arranged in a table whose first row of 16 -; bytes corresponds to drive 0, with the last row corresponding to drive n-1. -; In the following figure the label DPBASE defines the base address of the -; DPH table. -; -; DPBASE: -; 00 XLT00 0000 0000 0000 DIRBUF DBP00 CSV00 ALV00 -; 01 XLT01 0000 0000 0000 DIRBUF DBP01 CSV01 ALV01 -; (and so on through) -; n-1 XLTn-1 0000 0000 0000 DIRBUF DBPn-1 CSVn-1 ALVn-1 - -; -; The translation vectors, XLT00 through XLTn-1, are located elsewhere in the -; BIOS, and simply correspond one-for-one with the logical sector numbers -; zero through the sector count 1. The Disk Parameter Block (DPB) for each -; drive is more complex. As shown below, particular DPB, that is addressed by -; one or more DPHS, takes the general form: -; -; +---+---+---+---+---+---+---+---+---+---+ -; |SPT|BSH|BLM|EXM|DSM|DRM|AL0|AL1|CKS|OFF| -; +---+---+---+---+---+---+---+---+---+---+ -; 16B 8B 8B 8B 16B 16B 8B 8B 16B 16B -; -; where each is a byte or word value, as shown by the 8b or 16b indicator -; below the field. -; -; The following field abbreviations are used in the figure above: -; SPT is the total number of sectors per track. -; BSH is the data allocation block shift factor, determined by -; the data block allocation size. -; BLM is the data allocation block mask (2[BSH-1]). -; EXM is the extent mask, determined by the data block -; allocation size and the number of disk blocks. -; DSM determines the total storage capacity of the disk drive. -; DRM determines the total number of directory entries that -; can be stored on this drive. -; AL0, AL1 determine reserved directory blocks. -; CKS is the size of the directory check vector. -; -; OFF is the number of reserved tracks at the beginning of the -; (logical) disk. -; -; The values of BSH and BLM determine the data allocation size BLS, which is -; not an entry in the DPB. Given that the designer has selected a value for -; BLS, the values of BSH and BLM are shown in the following table. -; -; BLS BSH BLM -; 1,024 3 7 -; 2,048 4 15 -; 4,096 5 31 -; 8,192 6 63 -; 16,384 7 127 -; -; where all values are in decimal. The value of EXM depends upon both the BLS -; and whether the DSM value is less than 256 or greater than 255, as shown in -; the table below. -; -; EXM values -; BLS DSM<256 DSM>255 -; 1,024 0 N/A -; 2,048 1 0 -; 4,096 3 1 -; 8,192 7 3 -; 16,384 15 7 -; -; The value of DSM is the maximum data block number supported by this -; particular drive, measured in BLS units. The product (DSM + 1) is the total -; number of bytes held by the drive and must be within the capacity of the -; physical disk, not counting the reserved operating system tracks. -; -; The DRM entry is the one less than the total number of directory entries -; that can take on a 16-bit value. The values of AL0 and AL1, however, are -; determined by DRM. The values AL0 and AL1 can together be considered a -; string of 16-bits, as shown below. -; -; |--------- AL0 ---------|-------- AL1 ----------| -; 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 -; -; Position 00 corresponds to the high-order bit of the byte labeled AL0 and -; 15 corresponds to the low-order bit of the byte labeled AL1. Each bit -; position reserves a data block for number of directory entries, thus -; allowing a total of 16 data blocks to be assigned for directory entries -; (bits are assigned starting at 00 and filled to the right until position -; 15). Each directory entry occupies 32 bytes, resulting in the following -; tabulation: -; -; BLS Directory Entries -; 1,024 32 times # bits -; 2,048 64 times # bits -; 4,096 128 times # bits -; 8,192 256 times # bits -; 16,384 512 times # bits -; -; Thus, if DRM = 127 (128 directory entries) and BLS = 1024, there are 32 -; directory entries per block, requiring 4 reserved blocks. In this case, the -; 4 high-order bits of AL0 are set, resulting in the values AL0 = 0F0H and -; AL1 = 00H. -; -; The CKS value is determined as follows: if the disk drive media is -; removable, then CKS = (DRM + 1)/4, where DRM is the last directory entry -; number. If the media are fixed, then set CKS = 0 (no directory records are -; checked in this case). -; -; Finally, the OFF field determines the number of tracks that are skipped at -; the beginning of the physical disk. This value is automatically added -; whenever SETTRK is called and can be used as a mechanism for skipping -; reserved operating system tracks or for partitioning a large disk into -; smaller segmented sections. -; -; To complete the discussion of the DPB, several DPHs can address the same -; DPB if their drive characteristics are identical. Further, the DPB can be -; dynamically changed when a new drive is addressed by simply changing the -; pointer in the DPH; because the BDOS copies the DPB values to a local area -; whenever the SELDSK function is invoked. -; -; Returning back to DPH for a particular drive, the two address values CSV -; and ALV remain. Both addresses reference an area of uninitialized memory -; following the BIOS. The areas must be unique for each drive, and the size -; of each area is determined by the values in the DPB. -; -; The size of the area addressed by CSV is CKS bytes, which is sufficient to -; hold the directory check information for this particular drive. If CKS = -; (DRM + 1)/4, you must reserve (DRM + 1)/4 bytes for directory check use. If -; CKS = 0, no storage is reserved. -; -; The size of the area addressed by ALV is determined by the maximum number -; of data blocks allowed for this particular disk and is computed as (DSM/8) -; + 1. - -; -; diskette drives -; -dpbase equ $ - dw atrans,0,0,0,dirbf,mits2,chk00,all00 - dw atrans,0,0,0,dirbf,mits2,chk01,all01 - dw atrans,0,0,0,dirbf,mits2,chk02,all02 - dw atrans,0,0,0,dirbf,mits2,chk03,all03 - dw atrans,0,0,0,dirbf,mits2,chk04,all04 - dw atrans,0,0,0,dirbf,mits2,chk05,all05 - dw atrans,0,0,0,dirbf,mits2,chk06,all06 - dw atrans,0,0,0,dirbf,mits, chk07,all07 - - if nhdisks gt 0 -defdw macro ?value - dw all0&?value - endm - -defdp macro ?number - local ?hdi -?hdi defl 8 - rept ?number - dw 0,0,0,0,dirbf,simhd,0 - defdw %?hdi -?hdi defl ?hdi+1 - endm - endm - - defdp nhdisks - -simhd: dw spt ; SPT, sectors per track - db 5 ; BSH, data allocation block shift factor, for BLS=4,096 - db 31 ; BLM, data allocation block mask, for BLS=4,096 - db 1 ; extent mask for BLS=4,096 and DSM>255 - dw 2047-restrk ; DSM, maximum data block number - dw 1023 ; DRM, number of directory entries - 1 - db 0ffh,0 ; AL0, AL1, 8 blocks reserved to hold all entries - ; (number of directory entries)*32 = (number of reserved blocks)*(block size BLS) - ; 1024 * 32 = 8 * 4096 - dw 0 ; CKS, set 0 since hard disk is fixed - dw restrk ; OFF, number of tracks skipped at beginning of disk - db 0 ; PSH - db 0 ; PHM - endif - -; copylib (default) format -mits: dw spt ; spt, sectors per track - db 3 ; allocation block shift factor, bsh - db 7 ; data allocation block mask, blm, allocation size (bls) = 1024 - db 0 ; extent mask - dw dsm07 ; dsm, maximum data block number - dw dirent ; drm, number of directory entries - 1 - db 0ffh,0 ; al0, al1, 8 blocks reserved to hold all entries - ; 256 * 32 = 8 * 1024 - ; (drm+1) * 32 = (number of bits in al0 and al1) * bls - dw cks ; cks = (drm + 1)/4 - dw restrk ; off, number of tracks skipped at beginning of disk - db 0 ; PSH - db 0 ; PHM - -mits2: dw spt ; spt, sectors per track - db 4 ; allocation block shift factor, bsh - db 15 ; data allocation block mask, blm, allocation size (bls) = 2048 - db 0 ; extent mask - dw dsm06 ; dsm, maximum data block number - dw dirent ; drm, number of directory entries - 1 - db 0f0h,0 ; al0, al1, 4 blocks reserved to hold all entries - ; 256 * 32 = 4 * 2048 - ; (drm+1) * 32 = (number of bits in al0 and al1) * bls - dw cks ; cks = (drm + 1)/4 - dw restrk ; off, number of tracks skipped at beginning of disk - db 0 ; PSH - db 0 ; PHM - -; speedball (copylib) skewtable -atrans: db 01,18,03,20,05,22,07,24 - db 09,26,11,28,13,30,15,32 - db 17,02,19,04,21,06,23,08 - db 25,10,27,12,29,14,31,16 - -msg1: db cr, lf - db '0' + (msize/10) - db '0' + (msize MOD 10) - db 'K Dougs CP/M Version 2.2 (SIMH ALTAIR 8800, BIOS V1.27, ' - - if nhdisks gt 0 - db '0' + nhdisks - db ' HD, ' - endif - - db '02-May-2009)' - db cr, lf, '$' - - if needZ80 -msg2: db cr, lf, '8080 CPU detected. Need Z80.', cr, lf, '$' - endif - -secmsg: db cr, lf, 'Cannot find sector in register ', cr, lf, '$' - -; position disk drive head -ontrk0: db track1 ; current track# drive 0 (logical 1) - db track1 ; current track# drive 1 (logical 2) - db track1 ; current track# drive 2 (logical 3) - db track1 ; current track# drive 3 (logical 4) - db track1 ; current track# drive 4 (logical 5) - db track1 ; current track# drive 5 (logical 6) - db track1 ; current track# drive 6 (logical 7) - db track1 ; current track# drive 7 (logical 8) - -diskno: db 0 -sector: db 0 -track: dw 0 -dmaad: dw 0 - -; begin scratch area for bdos -dirbf: ds 128 ; directory work space -all00: ds ((dsm06+1)/8)+1 -all01: ds ((dsm06+1)/8)+1 -all02: ds ((dsm06+1)/8)+1 -all03: ds ((dsm06+1)/8)+1 -all04: ds ((dsm06+1)/8)+1 -all05: ds ((dsm06+1)/8)+1 -all06: ds ((dsm06+1)/8)+1 -all07: ds ((dsm07+1)/8)+1 - - if nhdisks gt 0 - -deflab macro ?value -all0&?value equ $ - endm - -defall macro ?number - local ?hdi -?hdi defl 8 - rept ?number - deflab %?hdi - ds 256 -?hdi defl ?hdi+1 - endm - endm - - defall nhdisks - endif - -chk00: ds cks -chk01: ds cks -chk02: ds cks -chk03: ds cks -chk04: ds cks -chk05: ds cks -chk06: ds cks -chk07: ds cks -altbuf: ds asecsiz+1 - -biosend equ $ -biossiz equ biosend-bios - -; fill remainder with 0 - -fillmod equ biossiz AND 00ffh - if fillmod gt 0 -fillsiz equ 100h-fillmod - ds fillsiz - endif - - if2 -padjust macro ?newsiz - .printx /Adjust bioslen in MEMCFG.LIB to ?newsiz/ - endm - -psize macro ?val1,?val2,?val3,?val4 - .printx /BIOS extends from ?val1 to ?val2 (Size ?val3, bioslen = ?val4)/ - endm - -psave macro ?value - .printx /SAVE ?value CPMBOOT.COM/ - endm - - .radix 16 - psize %bios,%biosend,%biossiz,%bioslen - if biossiz gt bioslen - padjust %(100h*((biossiz + 0ffh) / 100h)) - endif - .radix 10 - if biosend gt 0ff00h - .printx /Warning: BIOS extends into Altair ROM/ - endif - - psave %(9+(ccplen + bdoslen + bioslen) / 100h) - - endif - - .dephase - - end diff --git a/doug/src/driccp.mac b/doug/src/driccp.mac deleted file mode 100755 index 38d61a66..00000000 --- a/doug/src/driccp.mac +++ /dev/null @@ -1,1205 +0,0 @@ - title 'console command processor (CCP), ver 2.0' - - .Z80 - aseg - org 100h - maclib MEMCFG.LIB ; define configuration parameters - .phase ccpph ; CCPLOC not needed, we use ccpph instead - -; assembly language version of the CP/M console command processor -; -; version 2.2 February, 1980 - -; Copyright (c) 1976, 1977, 1978, 1979, 1980 -; Digital Research -; Box 579, Pacific Grove, -; California, 93950 - -bdosl equ bdosph ;bdos location -tran equ 100h -tranm equ $ -ccploc equ $ - -; ******************************************************** -; * Base of CCP contains the following code/data * -; * ccp: jmp ccpstart (start with command) * -; * jmp ccpclear (start, clear command) * -; * ccp+6 127 (max command length) * -; * ccp+7 comlen (command length = 00) * -; * ccp+8 ' ... ' (16 blanks) * -; ******************************************************** -; * Normal entry is at ccp, where the command line given * -; * at ccp+8 is executed automatically (normally a null * -; * command with comlen = 00). An initializing program * -; * can be automatically loaded by storing the command * -; * at ccp+8, with the command length at ccp+7. In this * -; * case, the ccp executes the command before prompting * -; * the console for input. Note that the command is exe-* -; * cuted on both warm and cold starts. When the command* -; * line is initialized, a jump to "jmp ccpclear" dis- * -; * ables the automatic command execution. * -; ******************************************************** - - jp ccpstart ;start ccp with possible initial command - jp ccpclear ;clear the command buffer -maxlen: db 127 ;max buffer length -comlen: db 0 ;command length (filled in by dos) - -; (command executed initially if comlen non zero) -combuf: db ' ' ;8 character fill - db ' ' ;8 character fill - db 'COPYRIGHT (C) 1979, DIGITAL RESEARCH '; 38 - ds 128-($-combuf) -; total buffer length is 128 characters - -comaddr: - dw combuf ;address of next to char to scan -staddr: ds 2 ;starting address of current fillfcb request - -diska equ 0004h ;disk address for current disk -bdos equ 0005h ;primary bdos entry point -buff equ 0080h ;default buffer -fcb equ 005ch ;default file control block - -rcharf equ 1 ;read character function -pcharf equ 2 ;print character function -pbuff equ 9 ;print buffer function -rbuff equ 10 ;read buffer function -breakf equ 11 ;break key function -liftf equ 12 ;lift head function (no operation) -initf equ 13 ;initialize bdos function -self equ 14 ;select disk function -openf equ 15 ;open file function -closef equ 16 ;close file function -searf equ 17 ;search for file function -searnf equ 18 ;search for next file function -delf equ 19 ;delete file function -dreadf equ 20 ;disk read function -dwritf equ 21 ;disk write function -makef equ 22 ;file make function -renf equ 23 ;rename file function -logf equ 24 ;return login vector -cself equ 25 ;return currently selected drive number -dmaf equ 26 ;set dma address -userf equ 32 ;set user number - -; special fcb flags -rofile equ 9 ;read only file -sysfile equ 10 ;system file flag - -; special characters -cr equ 13 ;carriage return -lf equ 10 ;line feed -la equ 5fh ;left arrow -eofile equ 1ah ;end of file - -; utility procedures -printchar: - ld e,a - ld c,pcharf - jp bdos - -printbc: ;print character, but save b,c registers - push bc - call printchar - pop bc - ret - -crlf: ld a,cr - call printbc - ld a,lf - jp printbc - -blank: ld a,' ' - jp printbc - -print: ;print string starting at b,c until next 00 entry - push bc - call crlf - pop hl ;now print the string -prin0: ld a,(hl) - or a - ret z ;stop on 00 - inc hl - push hl ;ready for next - call printchar - pop hl ;character printed - jp prin0 ;for another character - -initialize: - ld c,initf - jp bdos - -select: ld e,a - ld c,self - jp bdos - -bdos$inr: - call bdos - ld (dcnt),a - inc a - ret - -open: ;open the file given by d,e - ld c,openf - jp bdos$inr - -openc: ;open comfcb - xor a - ld (comrec),a ;clear next record to read - ld de,comfcb - jp open - -close: ;close the file given by d,e - ld c,closef - jp bdos$inr - -search: ;search for the file given by d,e - ld c,searf - jp bdos$inr - -searchn: ;search for the next occurrence of the file given by d,e - ld c,searnf - jp bdos$inr - -searchcom: ;search for comfcb file - ld de,comfcb - jp search - -delete: ;delete the file given by d,e - ld c,delf - jp bdos - -bdos$cond: - call bdos - or a - ret - -diskread: ;read the next record from the file given by d,e - ld c,dreadf - jp bdos$cond - -diskreadc: ;read the comfcb file - ld de,comfcb - jp diskread - -diskwrite: ;write the next record to the file given by d,e - ld c,dwritf - jp bdos$cond - -make: ;create the file given by d,e - ld c,makef - jp bdos$inr - -renam: ;rename the file given by d,e - ld c,renf - jp bdos - -getuser: ;return current user code in a - ld e,0ffh ;drop through to setuser - -setuser: - ld c,userf - jp bdos ;sets user number - -saveuser: ;save user#/disk# before possible ^c or transient - call getuser ;code to a - add a,a - add a,a - add a,a - add a,a ;rot left - ld hl,cdisk - or (hl) ;4b=user, 4b=disk - ld (diska),a ;stored away in memory for later - ret - -setdiska: - ld a,(cdisk) - ld (diska),a ;user/disk - ret - -translate: ;translate character in register A to upper case - cp 61h - ret c ;return if below lower case a - cp 7bh - ret nc ;return if above lower case z - and 5fh - ret ;translated to upper case - -readcom: ;read the next command into the command buffer - ;check for submit file - ld a,(submit) - or a - jp z,nosub - ;scanning a submit file - ;change drives to open and read the file - ld a,(cdisk) - or a - ld a,0 - call nz,select - ;have to open again in case xsub present - ld de,subfcb - call open - jp z,nosub ;skip if no sub - ld a,(subrc) - dec a ;read last record(s) first - ld (subcr),a ;current record to read - ld de,subfcb - call diskread ;end of file if last record - jp nz,nosub - ;disk read is ok, transfer to combuf - ld de,comlen - ld hl,buff - ld b,128 - call move0 - ;line is transferred, close the file with a - ;deleted record - ld hl,submod - ld (hl),0 ;clear fwflag - inc hl - dec (hl) ;one less record - ld de,subfcb - call close - jp z,nosub - ;close went ok, return to original drive - ld a,(cdisk) - or a - call nz,select - ;print to the 00 - ld hl,combuf - call prin0 - call break$key - jp z,noread - call del$sub - jp ccp ;break key depressed - -nosub: ;no submit file - call del$sub - ;translate to upper case, store zero at end - call saveuser ;user # save in case control c - ld c,rbuff - ld de,maxlen - call bdos - call setdiska ;no control c, so restore diska -noread: ;enter here from submit file - ;set the last character to zero for later scans - ld hl,comlen - ld b,(hl) ;length is in b -readcom0: - inc hl - ld a,b - or a ;end of scan? - jp z,readcom1 - ld a,(hl) ;get character and translate - call translate - ld (hl),a - dec b - jp readcom0 - -readcom1: ;end of scan, h,l address end of command - ld (hl),a ;store a zero - ld hl,combuf - ld (comaddr),hl ;ready to scan to zero - ret - -break$key: ;check for a character ready at the console - ld c,breakf - call bdos - or a - ret z - ld c,rcharf - call bdos ;character cleared - or a - ret - -cselect: ;get the currently selected drive number to reg-A - ld c,cself - jp bdos - -setdmabuff: ;set default buffer dma address - ld de,buff ;(drop through) - -setdma: ;set dma address to d,e - ld c,dmaf - jp bdos - -del$sub: ;delete the submit file, and set submit flag to false - ld hl,submit - ld a,(hl) - or a - ret z ;return if no sub file - ld (hl),0 ;submit flag is set to false - xor a - call select ;on drive a to erase file - ld de,subfcb - call delete - ld a,(cdisk) - jp select ;back to original drive - -serialize: ;check serialization - ld de,serial - ld hl,bdosl - ld b,6 ;check six bytes -ser0: ld a,(de) - cp (hl) - jp nz,badserial - inc de - inc hl - dec b - jp nz,ser0 - ret ;serial number is ok - -comerr: ;error in command string starting at position - ;'staddr' and ending with first delimiter - call crlf ;space to next line - ld hl,(staddr) ;h,l address first to print -comerr0: ;print characters until blank or zero - ld a,(hl) - cp ' ' - jp z,comerr1 ; not blank - or a - jp z,comerr1 ; not zero, so print it - push hl - call printchar - pop hl - inc hl - jp comerr0 ; for another character -comerr1: ;print question mark,and delete sub file - ld a,'?' - call printchar - call crlf - call del$sub - jp ccp ;restart with next command - - ; fcb scan and fill subroutine (entry is at fillfcb below) - ;fill the comfcb, indexed by A (0 or 16) - ;subroutines -delim: ;look for a delimiter - ld a,(de) - or a - ret z ;not the last element - cp ' ' - jp c,comerr ;non graphic - ret z ;treat blank as delimiter - cp '=' - ret z - cp la - ret z ;left arrow - cp '.' - ret z - cp ':' - ret z - cp ';' - ret z - cp '<' - ret z - cp '>' - ret z - ret ;delimiter not found - -deblank: ;deblank the input line - ld a,(de) - or a - ret z ;treat end of line as blank - cp ' ' - ret nz - inc de - jp deblank - -addh: ;add a to h,l - add a,l - ld l,a - ret nc - inc h - ret - -fillfcb0: ;equivalent to fillfcb(0) - ld a,0 - -fillfcb: - ld hl,comfcb - call addh - push hl - push hl ;fcb rescanned at end - xor a - ld (sdisk),a ;clear selected disk (in case A:...) - ld hl,(comaddr) - ex de,hl ;command address in d,e - call deblank ;to first non-blank character - ex de,hl - ld (staddr),hl ;in case of errors - ex de,hl - pop hl ;d,e has command, h,l has fcb address - ;look for preceding file name A: B: ... - ld a,(de) - or a - jp z,setcur0 ;use current disk if empty command - sbc a,'A'-1 - ld b,a ;disk name held in b if : follows - inc de - ld a,(de) - cp ':' - jp z,setdsk ;set disk name if : - -setcur: ;set current disk - dec de ;back to first character of command -setcur0: - ld a,(cdisk) - ld (hl),a - jp setname - -setdsk: ;set disk to name in register b - ld a,b - ld (sdisk),a ;mark as disk selected - ld (hl),b - inc de ;past the : - -setname: ;set the file name field - ld b,8 ;file name length (max) -setnam0: call delim - jp z,padname ;not a delimiter - inc hl - cp '*' - jp nz,setnam1 ;must be ?'s - ld (hl),'?' - jp setnam2 ;to dec count - -setnam1: - ld (hl),a ;store character to fcb - inc de -setnam2: - dec b ;count down length - jp nz,setnam0 - - ;end of name, truncate remainder -trname: call delim - jp z,setty ;set type field if delimiter - inc de - jp trname - -padname: - inc hl - ld (hl),' ' - dec b - jp nz,padname - -setty: ;set the type field - ld b,3 - cp '.' - jp nz,padty ;skip the type field if no . - inc de ;past the ., to the file type field -setty0: ;set the field from the command buffer - call delim - jp z,padty - inc hl - cp '*' - jp nz,setty1 - ld (hl),'?' ;since * specified - jp setty2 - -setty1: ;not a *, so copy to type field - ld (hl),a - inc de -setty2: ;decrement count and go again - dec b - jp nz,setty0 - - ;end of type field, truncate -trtyp: ;truncate type field - call delim - jp z,efill - inc de - jp trtyp - -padty: ;pad the type field with blanks - inc hl - ld (hl),' ' - dec b - jp nz,padty - -efill: ;end of the filename/filetype fill, save command address - ;fill the remaining fields for the fcb - ld b,3 -efill0: inc hl - ld (hl),0 - dec b - jp nz,efill0 - ex de,hl - ld (comaddr),hl ;set new starting point - - ;recover the start address of the fcb and count ?'s - pop hl - ld bc,11 ;b=0, c=8+3 -scnq: inc hl - ld a,(hl) - cp '?' - jp nz,scnq0 - ;? found, count it in b - inc b -scnq0: dec c - jp nz,scnq - ;number of ?'s in c, move to a and return with flags set - ld a,b - or a - ret - -intvec: ;intrinsic function names (all are four characters) - db 'DIR ' - db 'ERA ' - db 'TYPE' - db 'SAVE' - db 'REN ' - db 'USER' -intlen equ ($-intvec)/4 ;intrinsic function length -serial: db 0,0,0,0,0,0 - - -intrinsic: ;look for intrinsic functions (comfcb has been filled) - ld hl,intvec - ld c,0 ;c counts intrinsics as scanned -intrin0: - ld a,c - cp intlen ;done with scan? - ret nc - ;no, more to scan - ld de,comfcb+1 ;beginning of name - ld b,4 ;length of match is in b -intrin1: - ld a,(de) - cp (hl) ;match? - jp nz,intrin2 ;skip if no match - inc de - inc hl - dec b - jp nz,intrin1 ;loop while matching - ;complete match on name, check for blank in fcb - ld a,(de) - cp ' ' - jp nz,intrin3 ;otherwise matched - ld a,c - ret ;with intrinsic number in a - -intrin2: ;mismatch, move to end of intrinsic - inc hl - dec b - jp nz,intrin2 - -intrin3: ;try next intrinsic - inc c ;to next intrinsic number - jp intrin0 ;for another round - -ccpclear: ;clear the command buffer - xor a - ld (comlen),a - ;drop through to start ccp -ccpstart: ;enter here from boot loader - ld sp,stack - push bc ;save initial disk number - ;(high order 4bits=user code, low 4bits=disk#) - ld a,c - rra - rra - rra - rra - and 0fh ;user code - ld e,a - call setuser ;user code selected - ;initialize for this user, get $ flag - call initialize ;0ffh in accum if $ file present - ld (submit),a ;submit flag set if $ file present - pop bc ;recall user code and disk number - ld a,c - and 0fh ;disk number in accumulator - ld (cdisk),a ;clears user code nibble - call select ;proper disk is selected, now check sub files - ;check for initial command - ld a,(comlen) - or a - jp nz,ccp0 ;assume typed already - -ccp: ;enter here on each command or error condition - ld sp,stack - call crlf ;print d> prompt, where d is disk name - call cselect ;get current disk number - add a,'A' - call printchar - ld a,'>' - call printchar - call readcom ;command buffer filled -ccp0: ;(enter here from initialization with command full) - ld de,buff - call setdma ;default dma address at buff - call cselect - ld (cdisk),a ;current disk number saved - call fillfcb0 ;command fcb filled - call nz,comerr ;the name cannot be an ambiguous reference - ld a,(sdisk) - or a - jp nz,userfunc - ;check for an intrinsic function - call intrinsic - ld hl,jmptab ;index is in the accumulator - ld e,a - ld d,0 - add hl,de - add hl,de ;index in d,e - ld a,(hl) - inc hl - ld h,(hl) - ld l,a - jp (hl) - ;pc changes to the proper intrinsic or user function -jmptab: dw direct ;directory search - dw erase ;file erase - dw type ;type file - dw save ;save memory image - dw rename ;file rename - dw user ;user number - dw userfunc ;user-defined function -badserial: - ld hl,76f3h ;'di hlt' instructions. [di or (hlt shl 8)] - ld (ccploc),hl - ld hl,ccploc - jp (hl) - - - ;utility subroutines for intrinsic handlers -readerr: ;print the read error message - ld bc,rdmsg - jp print -rdmsg: db 'READ ERROR',0 - -nofile: ;print no file message - ld bc,nofmsg - jp print -nofmsg: db 'NO FILE',0 - -getnumber: ;read a number from the command line - call fillfcb0 ;should be number - ld a,(sdisk) - or a - jp nz,comerr ;cannot be prefixed - ;convert the byte value in comfcb to binary - ld hl,comfcb+1 - ld bc,11 ;(b=0, c=11) - ;value accumulated in b, c counts name length to zero -conv0: ld a,(hl) - cp ' ' - jp z,conv1 - ;more to scan, convert char to binary and add - inc hl - sub '0' - cp 10 - jp nc,comerr ;valid? - ld d,a ;save value - ld a,b ;mult by 10 - and 11100000b - jp nz,comerr - ld a,b ;recover value - rlca - rlca - rlca ;*8 - add a,b - jp c,comerr - add a,b - jp c,comerr ;*8+*2 = *10 - add a,d - jp c,comerr ;+digit - ld b,a - dec c - jp nz,conv0 ;for another digit - ret -conv1: ;end of digits, check for all blanks - ld a,(hl) - cp ' ' - jp nz,comerr ;blanks? - inc hl - dec c - jp nz,conv1 - ld a,b ;recover value - ret - -movename: ;move 3 characters from h,l to d,e addresses - ld b,3 -move0: ld a,(hl) - ld (de),a - inc hl - inc de - dec b - jp nz,move0 - ret - -addhcf: ;buff + a + c to h,l followed by fetch - ld hl,buff - add a,c - call addh - ld a,(hl) - ret - -setdisk: ;change disks for this command, if requested - xor a - ld (comfcb),a ;clear disk name from fcb - ld a,(sdisk) - or a - ret z ;no action if not specified - dec a - ld hl,cdisk - cp (hl) - ret z ;already selected - jp select - -resetdisk: ;return to original disk after command - ld a,(sdisk) - or a - ret z ;no action if not selected - dec a - ld hl,cdisk - cp (hl) - ret z ;same disk - ld a,(cdisk) - jp select - - ;individual intrinsics follow -direct: ;directory search - call fillfcb0 ;comfcb gets file name - call setdisk ;change disk drives if requested - ld hl,comfcb+1 - ld a,(hl) ;may be empty request - cp ' ' - jp nz,dir1 ;skip fill of ??? if not blank - ;set comfcb to all ??? for current disk - ld b,11 ;length of fill ????????.??? -dir0: ld (hl),'?' - inc hl - dec b - jp nz,dir0 - ;not a blank request, must be in comfcb -dir1: ld e,0 - push de ;E counts directory entries - call searchcom ;first one has been found - call z,nofile ;not found message -dir2: jp z,endir - ;found, but may be system file - ld a,(dcnt) ;get the location of the element - rrca - rrca - rrca - and 1100000b - ld c,a - ;c contains base index into buff for dir entry - ld a,sysfile - call addhcf ;value to A - rla - jp c,dir6 ;skip if system file - ;c holds index into buffer - ;another fcb found, new line? - pop de - ld a,e - inc e - push de - ;e=0,1,2,3,...new line if mod 4 = 0 - and 11b - push af ;and save the test - jp nz,dirhdr0 ;header on current line - call crlf - push bc - call cselect - pop bc - ;current disk in A - add a,'A' - call printbc - ld a,':' - call printbc - jp dirhdr1 ;skip current line hdr -dirhdr0: - call blank ;after last one - ld a,':' - call printbc -dirhdr1: - call blank - ;compute position of name in buffer - ld b,1 ;start with first character of name -dir3: ld a,b - call addhcf ;buff+a+c fetched - and 7fh ;mask flags - ;may delete trailing blanks - cp ' ' - jp nz,dir4 ;check for blank type - pop af - push af ;may be 3rd item - cp 3 - jp nz,dirb ;place blank at end if not - ld a,9 - call addhcf ;first char of type - and 7fh - cp ' ' - jp z,dir5 - ;not a blank in the file type field -dirb: ld a,' ' ;restore trailing filename chr -dir4: - call printbc ;char printed - inc b - ld a,b - cp 12 - jp nc,dir5 - ;check for break between names - cp 9 - jp nz,dir3 ;for another char - ;print a blank between names - call blank - jp dir3 - -dir5: ;end of current entry - pop af ;discard the directory counter (mod 4) -dir6: call break$key ;check for interrupt at keyboard - jp nz,endir ;abort directory search - call searchn - jp dir2 ;for another entry -endir: ;end of directory scan - pop de ;discard directory counter - jp retcom - - -erase: call fillfcb0 ;cannot be all ???'s - cp 11 - jp nz,erasefile - ;erasing all of the disk - ld bc,ermsg - call print - call readcom - ld hl,comlen - dec (hl) - jp nz,ccp ;bad input - inc hl - ld a,(hl) - cp 'Y' - jp nz,ccp - ;ok, erase the entire diskette - inc hl - ld (comaddr),hl ;otherwise error at retcom -erasefile: - call setdisk - ld de,comfcb - call delete - inc a ;255 returned if not found - call z,nofile ;no file message if so - jp retcom - -ermsg: db 'ALL (Y/N)?',0 - -type: call fillfcb0 - jp nz,comerr ;don't allow ?'s in file name - call setdisk - call openc ;open the file - jp z,typerr ;zero flag indicates not found - ;file opened, read 'til eof - call crlf - ld hl,bptr - ld (hl),255 ;read first buffer -type0: ;loop on bptr - ld hl,bptr - ld a,(hl) - cp 128 ;end buffer - jp c,type1 - push hl ;carry if 0,1,...,127 - ;read another buffer full - call diskreadc - pop hl ;recover address of bptr - jp nz,typeof ;hard end of file - xor a - ld (hl),a ;bptr = 0 -type1: ;read character at bptr and print - inc (hl) ;bptr = bptr + 1 - ld hl,buff - call addh ;h,l addresses char - ld a,(hl) - cp eofile - jp z,retcom - call printchar - call break$key - jp nz,retcom ;abort if break - jp type0 ;for another character - -typeof: ;end of file, check for errors - dec a - jp z,retcom - call readerr -typerr: call resetdisk - jp comerr - -save: call getnumber ; value to register a - push af ;save it for later - ;should be followed by a file to save the memory image - call fillfcb0 - jp nz,comerr ;cannot be ambiguous - call setdisk ;may be a disk change - ld de,comfcb - push de - call delete ;existing file removed - pop de - call make ;create a new file on disk - jp z,saverr ;no directory space - xor a - ld (comrec),a ; clear next record field - pop af ;#pages to write is in a, change to #sectors - ld l,a - ld h,0 - add hl,hl - ld de,tran ;h,l is sector count, d,e is load address -save0: ;check for sector count zero - ld a,h - or l - jp z,save1 ;may be completed - dec hl ;sector count = sector count - 1 - push hl ;save it for next time around - ld hl,128 - add hl,de - push hl ;next dma address saved - call setdma ;current dma address set - ld de,comfcb - call diskwrite - pop de - pop hl ;dma address, sector count - jp nz,saverr ;may be disk full case - jp save0 ;for another sector - -save1: ;end of dump, close the file - ld de,comfcb - call close - inc a ; 255 becomes 00 if error - jp nz,retsave ;for another command -saverr: ;must be full or read only disk - ld bc,fullmsg - call print -retsave: ;reset dma buffer - call setdmabuff - jp retcom - -fullmsg: - db 'NO SPACE',0 - -rename: ;rename a file on a specific disk - call fillfcb0 - jp nz,comerr ;must be unambiguous - ld a,(sdisk) - push af ;save for later compare - call setdisk ;disk selected - call searchcom ;is new name already there? - jp nz,renerr3 - ;file doesn't exist, move to second half of fcb - ld hl,comfcb - ld de,comfcb+16 - ld b,16 - call move0 - ;check for = or left arrow - ld hl,(comaddr) - ex de,hl - call deblank - cp '=' - jp z,ren1 ;ok if = - cp la - jp nz,renerr2 -ren1: ex de,hl - inc hl - ld (comaddr),hl ;past delimiter - ;proper delimiter found - call fillfcb0 - jp nz,renerr2 - ;check for drive conflict - pop af - ld b,a ;previous drive number - ld hl,sdisk - ld a,(hl) - or a - jp z,ren2 - ;drive name was specified. same one? - cp b - ld (hl),b - jp nz,renerr2 -ren2: ld (hl),b ;store the name in case drives switched - xor a - ld (comfcb),a - call searchcom ;is old file there? - jp z,renerr1 - - ;everything is ok, rename the file - ld de,comfcb - call renam - jp retcom - -renerr1: ; no file on disk - call nofile - jp retcom -renerr2: ; ambigous reference/name conflict - call resetdisk - jp comerr -renerr3: ; file already exists - ld bc,renmsg - call print - jp retcom -renmsg: db 'FILE EXISTS',0 - -user: ;set user number - call getnumber ; leaves the value in the accumulator - cp 16 - jp nc,comerr ; must be between 0 and 15 - ld e,a ;save for setuser call - ld a,(comfcb+1) - cp ' ' - jp z,comerr - call setuser ;new user number set - jp endcom - -userfunc: - call serialize ;check serialization - ;load user function and set up for execution - ld a,(comfcb+1) - cp ' ' - jp nz,user0 - ;no file name, but may be disk switch - ld a,(sdisk) - or a - jp z,endcom ;no disk name if 0 - dec a - ld (cdisk),a - call setdiska ;set user/disk - call select - jp endcom -user0: ;file name is present - ld de,comfcb+9 - ld a,(de) - cp ' ' - jp nz,comerr ;type ' ' - push de - call setdisk - pop de - ld hl,comtype ;.com - call movename ;file type is set to .com - call openc - jp z,userer - ;file opened properly, read it into memory - ld hl,tran ;transient program base -load0: push hl ;save dma address - ex de,hl - call setdma - ld de,comfcb - call diskread - jp nz,load1 - ;sector loaded, set new dma address and compare - pop hl - ld de,128 - add hl,de - ld de,tranm ;has the load overflowed? - ld a,l - sub e - ld a,h - sbc a,d - jp nc,loaderr - jp load0 ;for another sector - -load1: pop hl - dec a - jp nz,loaderr ;end file is 1 - call resetdisk ;back to original disk - call fillfcb0 - ld hl,sdisk - push hl - ld a,(hl) - ld (comfcb),a ;drive number set - ld a,16 - call fillfcb ;move entire fcb to memory - pop hl - ld a,(hl) - ld (comfcb+16),a - xor a - ld (comrec),a ;record number set to zero - ld de,fcb - ld hl,comfcb - ld b,33 - call move0 - ;move command line to buff - ld hl,combuf -bmove0: ld a,(hl) - or a - jp z,bmove1 - cp ' ' - jp z,bmove1 - inc hl - jp bmove0 ;for another scan - ;first blank position found -bmove1: ld b,0 - ld de,buff+1 - ;ready for the move -bmove2: ld a,(hl) - ld (de),a - or a - jp z,bmove3 - ;more to move - inc b - inc hl - inc de - jp bmove2 -bmove3: ;b has character count - ld a,b - ld (buff),a - call crlf - ;now go to the loaded program - call setdmabuff ;default dma - call saveuser ;user code saved - ;low memory diska contains user code - call tran ;gone to the loaded program - ld sp,stack ;may come back here - call setdiska - call select - jp ccp - -userer: ;arrive here on command error - call resetdisk - jp comerr - -loaderr: ;cannot load the program - ld bc,loadmsg - call print - jp retcom -loadmsg: - db 'BAD LOAD',0 -comtype: - db 'COM' ;for com files - - -retcom: ;reset disk before end of command check - call resetdisk - -endcom: ;end of intrinsic command - call fillfcb0 ;to check for garbage at end of line - ld a,(comfcb+1) - sub ' ' - ld hl,sdisk - or (hl) - ;0 in accumulator if no disk selected, and blank fcb - jp nz,comerr - jp ccp - -; data areas - ds 16 ;8 level stack -stack: - -; 'submit' file control block -submit: db 0 ;00 if no submit file, ff if submitting -subfcb: db 0,'$$$ ' ;file name is $$$ - db 'SUB',0,0 ;file type is sub -submod: db 0 ;module number -subrc: ds 1 ;record count filed - ds 16 ;disk map -subcr: ds 1 ;current record to read - -; command file control block -comfcb: ds 32 ;fields filled in later -comrec: ds 1 ;current record to read/write -dcnt: ds 1 ;disk directory count (used for error codes) -cdisk: ds 1 ;current disk -sdisk: ds 1 ;selected disk for current operation - ;none=0, a=1, b=2 ... -bptr: ds 1 ;buffer pointer - - end ccploc diff --git a/doug/src/dwgh2b.c b/doug/src/dwgh2b.c deleted file mode 100755 index 53eb84c8..00000000 --- a/doug/src/dwgh2b.c +++ /dev/null @@ -1,128 +0,0 @@ -// --------------------------------------------------- -// hex2bin.c 21-May-11 Running on Mac OS X 10.6.6 -// S/n 2011-1042-654321 Written by Douglas W. Goodall -// Copyright(c)2011 Douglas W. Goodall, United States. -// --------------------------------------------------- -// This file is part of Vintage Modern Assembler Plus Tools. -// -// VMAPT is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// VMAPT is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with VMAPT. If not, see . -// - -#include -#include -#include - -#define DATA_RECORD 0x00 -#define EOF_RECORD 0x01 - -int main(int argc,char **argv) -{ - char g_szBuffer2[128]; - char szByteBuffer[2+1]; - char *p; - int i; - int iTemp; - - char cColon; - - char szLength[2+1]; - int iLength; - - char szAddress[4+1]; - unsigned int uiAddress; - - char szRecordType[2+1]; - unsigned char ucRecordType; - - char szData[80]; - unsigned char ucBinBuffer[32+1]; - - char szChecksum[2+1]; - unsigned char ucChecksum; - - unsigned int uiLastByte = 0; - - if(1 == argc) { - printf("usage - hex2bin \n"); - exit(EXIT_FAILURE); - } - - char szBinFile[255]; - char szHexFile[255]; - - strcpy(szHexFile,argv[1]); - strcpy(szBinFile,argv[1]); - - strcat(szBinFile,".bin"); - strcat(szHexFile,".hex"); - - unsigned char memory[0xfff0]; - memset(memory,0,sizeof(memory)); - - FILE * fhex = fopen(szHexFile,"r"); - if(NULL == fhex) { - printf("Sorry, cannot open %s for input\n",szHexFile); - exit(EXIT_FAILURE); - } - p = fgets(g_szBuffer2,sizeof(g_szBuffer2),fhex); - while(NULL != p) { - g_szBuffer2[strlen(g_szBuffer2)-1] = 0; - cColon = g_szBuffer2[0]; - - memset(szLength,0,sizeof(szLength)); - memcpy(szLength,&g_szBuffer2[1],2); - sscanf(szLength,"%02X",&iLength); - - memset(szAddress,0,sizeof(szAddress)); - memcpy(szAddress,&g_szBuffer2[3],4); - sscanf(szAddress,"%04X",&uiAddress); - - memset(szRecordType,0,sizeof(szRecordType)); - memcpy(szRecordType,&g_szBuffer2[7],2); - - sscanf(szRecordType,"%02X",&iTemp); - ucRecordType = (unsigned char)iTemp; - - if(0 == ucRecordType) { - memset(szData,0,sizeof(szData)); - memcpy(szData,&g_szBuffer2[9],iLength*2); - for(i=0;i -#include -#include - -#include "portab.h" -#ifndef __GNUC__ -#include "cpmbdos.h" -#include "cprintf.h" -#endif - -/* - * 1MB = 1,048,576 bytes - * 32MB = 1,048,576 * 32 = 33,554,432 - * - * physical sector is 512 bytes - * physical track is 256 sectors = 131,072 - * physical drive is 33,554,432 - * physical tracks are 33,554,432 / 131,072 = 256 - * physical tracks per physical drive are 256 - * - * logical sector is 128 bytes - * logical track is 256 sectors (aka ) - * logical drive is 8192KB (aka 8192KB/32KB = 256 logical tracks) - * - * - * 8,388,608 bytes is a logical drive - * 131,072 bytes is a physical track - * 8,388,608 / 131,072 = 64 physical tracks per logical drive - * - * One byte (0-255) will just hold the number of physical tracks needing - * to be shared amoung up to four logical drives. - * - * physical track 0 - partition sector and second-stage loader if needed - * physical tracks 1 - 64 = 8.0MB partition ( 64 * 131,072 = 8,388,608 ) - * physical tracks 65 - 128 = 8.0MB partition ( 64 * 131,072 = 8,388,608 ) - * physical tracks 129 - 192 = 8.0MB partition ( 64 * 131,072 = 8,388,608 ) - * physical tracks 193 - 255 = 7.9MB partition ( 63 * 131,072 = 8,257,536 ) - * - */ - -#define MAX_PARTS 4 -#define TRKS_PER_PHY_DRV 256 -#define TRKS_PER_LOG_DRV 64 /* 256 sectors * 512 = 128k */ - -#define SAFESTRING 80 /* make large enough to avoid accidental overrun */ - -#define U8 unsigned char - -struct PART_TABLE { /* in-memory instance of partition table */ - U8 start; /* starting track of a partition */ - U8 end; /* ending track of a partition */ -} pt[MAX_PARTS] = { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } }; - -U8 bRunning; /* scratchpad used used by the main loop */ -U8 end; /* scratchpad used to hold ending track of a part */ -U8 Index; /* scratchpad used as index for for loops */ -U8 NumParts; /* scratchpad to hold the current number of parts */ -U8 LastEnd; /* scratchpad to hold the last track allocated */ -U8 NewEnd; /* scratchpad to hold the proposed ending track */ -U8 NewMax; /* scratchpad to hold the proposed max part size */ -U8 NewSize; /* scratchpad to hold the decided new part size */ -U8 NewStart; /* scratchpad to hold the decided starting track */ -U8 start; /* scratchpad to hold the starting track of a part */ -U8 Avail; /* scratchpad to hold the remaining avialable tracks */ - -char szChoice[SAFESTRING]; /* string used to receive keystrokes */ -char szTemp[SAFESTRING]; /* string used for general purposes */ - -/* THESE ARE USED BY THE LIBRARY ROUTINES */ -#ifndef __GNUC__ -char getchar(void) -{ - struct BDOSCALL cread = { C_READ, { (unsigned int)0 } }; - return cpmbdos(&cread); -} -void outchar(char c) -{ - struct BDOSCALL cwrite = { C_WRITE, { (unsigned int)c } }; - cpmbdos(&cwrite); -} -#endif - -void display_menu(void) -{ - if(NumParts < MAX_PARTS) { - if(0 < Avail) { - printf("a - add partition #%d\n",NumParts+1); - } - } - if(0 < NumParts) { - printf("d - delete partition #%d\n",NumParts); - } - if(1 < NumParts) { - printf("D - delete all partitions, 1 - %d\n",NumParts); - } - if(0 == NumParts) { - printf("A - create all 8MB partitions\n"); - } - printf("q - quit fdisk\n\n"); -} - -char query(char *str) -{ - printf("%s",str); - gets(szTemp); - if('Y' == szTemp[0]) { - return TRUE; - } else { - return FALSE; - } -} - -void delete(void) -{ - if(0 < NumParts) { - if(TRUE == query("Delete partition(Y/n)?")) { - pt[NumParts-1].start = 0; - pt[NumParts-1].end = 0; - } - } -} - -void deleteall(void) -{ - if(0 < NumParts) { - if(TRUE == query("Delete all partitions(Y/n)?")) { - for(Index=0;Index'+$80 - .WORD W_0BRANCH -C_LLOOP: - .WORD 2+$ ; Vector to code - LD DE,0001 -C_ILOOP: - LD HL,(RPP) ; Get return stack pointer - LD A,(HL) ; Add DE to value on return stack - ADD A,E ; - LD (HL),A ; - LD E,A ; - INC HL ; - LD A,(HL) ; - ADC A,D ; - LD (HL),A ; - INC HL ; HL now points to limit value - INC D ; Get Ds sign bit - DEC D ; - LD D,A ; Result now in DE - JP M,DECR_LOOP ; Decrement loop so check > limit - ; otherwies check < limit - LD A,E ; Low byte back - SUB (HL) ; Subtract limit low - LD A,D ; High byte back - INC HL ; Point to limit high - SBC A,(HL) ; Subtract it - JR TEST_LIMIT ; -DECR_LOOP: - LD A,(HL) ; Get limit low - SUB E ; Subtract index low - INC HL ; Point to limit high - LD A,(HL) ; Get it - SBC A,D ; Subtract index high -TEST_LIMIT: - JP M,X_BRANCH ; Not reached limit so jump - INC HL ; Drop index & limit from return stack - LD (RPP),HL ; Save stack pointer - INC BC ; Skip branch offset - INC BC ; - JP NEXT - -W_PLOOP: ; Loop + stack & branch if not done - .BYTE $87,"<+LOOP",'>'+$80 - .WORD W_LLOOP -C_PLOOP: - .WORD 2+$ ; Vector to code - POP DE ; Get value from stack - JR C_ILOOP ; Go do loop increment - -W_LDO: ; Put start & end loop values on RPP - .BYTE $84,"'+$80 - .WORD W_PLOOP -C_LDO: - .WORD 2+$ - LD HL,(RPP) ; Get return stack pointer - DEC HL ; Add space for two values - DEC HL ; - DEC HL ; - DEC HL ; - LD (RPP),HL ; Save new stack pointer - POP DE ; Get start value & - LD (HL),E ; put on return stack top - INC HL ; - LD (HL),D ; - INC HL ; - POP DE ; Get end value & - LD (HL),E ; put on return stack - 1 - INC HL ; - LD (HL),D ; - JP NEXT - -W_I: ; Copy LOOP index to data stack - .BYTE $81,'I'+$80 - .WORD W_LDO -C_I: - .WORD 2+$ -X_I: - LD HL,(RPP) ; Get return stack pointer -X_I2: - LD E,(HL) ; Get LOOP index off return stack - INC HL ; - LD D,(HL) ; - PUSH DE ; Push onto data stack - JP NEXT - -W_DIGIT: ; Convert digit n2 using base n1 - .BYTE $85,"DIGI",'T'+$80 - .WORD W_I -C_DIGIT: - .WORD 2+$ - POP HL ; Get base to use - POP DE ; Get char - LD A,E ; A = char - SUB $30 ; Subtract 30h - JP M,NDIGIT - CP $0A ; Greater than 9 ? - JP M,LESS10 ; If not then skip - SUB $07 ; Convert 'A' to 10 - CP $0A ; Is it 10? - JP M,NDIGIT ; If not an error occured -LESS10: - CP L ; L is 1 digit limit - JP P,NDIGIT ; Out of range for digit - LD E,A ; Result into DE - LD HL,0001 ; Leave TRUE flag - JP NEXTS2 ; Save both & NEXT -NDIGIT: - LD L,H ; Leave FALSE flag - JP NEXTS1 ; Save & NEXT - -W_FIND: ; Find word & return vector,byte & flag - .BYTE $86,"'+$80 - .WORD W_DIGIT -C_FIND: - .WORD 2+$ ; Vector to code - POP DE ; Get pointer to next vocabulary word -COMPARE: - POP HL ; Copy pointer to word we're looking 4 - PUSH HL ; - LD A,(DE) ; Get 1st vocabulary word letter - XOR (HL) ; Compare with what we've got - AND $3F ; Ignore start flag - JR NZ,NOT_END_CHR ; No match so skip to next word -MATCH_NO_END: - INC HL ; Compare next chr - INC DE ; - LD A,(DE) ; - XOR (HL) ; - ADD A,A ; Move bit 7 to C flag - JR NZ,NO_MATCH ; No match jump - JR NC,MATCH_NO_END ; Match & not last, so next chr - LD HL,0005 ; Offset to start of code - ADD HL,DE ; HL now points to code start for word - EX (SP),HL ; Swap with value on stack -NOT_WORD_BYTE: - DEC DE ; Search back for word type byte - LD A,(DE) ; - OR A ; - JP P,NOT_WORD_BYTE ; Not yet so loop - LD E,A ; Byte into DE - LD D,$00 ; - LD HL,0001 ; Leave TRUE flag - JP NEXTS2 ; Save both & NEXT -NO_MATCH: - JR C,END_CHR ; If last chr then jump -NOT_END_CHR: - INC DE ; Next chr of this vocab word - LD A,(DE) ; Get it - OR A ; Set flags - JP P,NOT_END_CHR ; Loop if not end chr -END_CHR: - INC DE ; Now points to next word vector - EX DE,HL ; Swap - LD E,(HL) ; Vector into DE - INC HL ; - LD D,(HL) ; - LD A,D ; Check it's not last (first) word - OR E ; - JR NZ,COMPARE ; No error so loop - POP HL ; Dump pointer - LD HL,0000 ; Flag error - JP NEXTS1 ; Save & NEXT - -W_ENCLOSE: - .BYTE $87,"ENCLOS",'E'+$80 - .WORD W_FIND -C_ENCLOSE: - .WORD 2+$ ; Vector to code - POP DE ; get delimiter character - POP HL ; get address 1 - PUSH HL ; duplicate it - LD A,E ; delimiter char into A - LD D,A ; copy to D - LD E,$ff ;-1 for offset - DEC HL ; to allow for first INCR -J21E6: - INC HL ; point to next chr - INC E ; next offset - CP (HL) ; compare chr with (address) - JR Z,J21E6 ; loop if = delimiter chr - LD A,$0D ; else set CR - CP (HL) ; compare with (address) - LD A,D ; restore delimiter chr - JR Z,J21E6 ; loop if it was = CR - LD D,$00 ; zero high byte - PUSH DE ; save offset - LD D,A ; restore delimiter chr - LD A,(HL) ; get byte from address - AND A ; set the flags - JR NZ,J2202 ; branch if not null - LD D,$00 ; clear high byte - INC E ; point to next addr - PUSH DE ; save address - DEC E ; point to end - PUSH DE ; push address - JP NEXT ; done -J2202: - LD A,D ; restore delimiter chr - INC HL ; increment address - INC E ; increment offset - CP (HL) ; compare delimiter with (address) - JR Z,J2218 ; jump if = - LD A,$0D ; else get CR - CP (HL) ; compare with (address) - JR Z,J2218 ; jump if = - LD A,(HL) ; else get byte - AND A ; set the flags - JR NZ,J2202 ; loop if not null - LD D,$00 ; clear gigh byte - PUSH DE ; save address - PUSH DE ; save address - JP NEXT ; done -J2218: - LD D,$00 ; clear high byte - PUSH DE ; save address - INC E ; increment offset - PUSH DE ; save address - JP NEXT ; done - -W_EMIT: ; Output CHR from stack - .BYTE $84,"EMI",'T'+$80 - .WORD W_ENCLOSE -C_EMIT: - .WORD E_COLON ; Interpret following word sequence - .WORD C_UEMIT ; Put UEMIT addr on stack - .WORD C_FETCH ; Get UEMIT code field address - .WORD C_EXECUTE ; Jump to address on stack - .WORD C_1 - .WORD C_OUT - .WORD C_PLUSSTORE - .WORD C_STOP ; Pop BC from return stack (=next) - -W_KEY: ; Wait for key, value on stack - .BYTE $83,"KE",'Y'+$80 - .WORD W_EMIT -C_KEY: - .WORD 2+$ ; Vector to code - LD HL,(UKEY) ; Get the vector - JP (HL) ; Jump to it - -; .WORD E_COLON ; Interpret following word sequence -; .WORD C_UKEY ; Put UKEY addr on stack -; .WORD C_FETCH ; Get CF_KEY -; .WORD C_EXECUTE ; Jump to CF_KEY -; .WORD C_STOP ; Pop BC from return stack (=next) - - -W_TERMINAL: - .BYTE $89,"?TERMINA",'L'+$80 - .WORD W_KEY -C_TERMINAL: - .WORD E_COLON ; Interpret following word sequence - .WORD C_UTERMINAL - .WORD C_FETCH ; Get word from addr on stack - .WORD C_EXECUTE ; Jump to address on stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_CR: ; Output [CR][LF] - .BYTE $82,"C",'R'+$80 - .WORD W_TERMINAL -C_CR: - .WORD E_COLON ; Interpret following word sequence - .WORD C_UCR ; Push UCR addr - .WORD C_FETCH ; Get UCR code field addr - .WORD C_EXECUTE ; Jump to address on stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_CLS: ; Clear screen - .BYTE $83,"CL",'S'+$80 - .WORD W_CR -C_CLS: - .WORD E_COLON ; Interpret following word sequence - .WORD C_LIT ; Put clear screen code on stack - .WORD 000Ch ; - .WORD C_EMIT ; Output it - .WORD C_STOP ; Pop BC from return stack (=next) - -W_CMOVE: ; Move block - .BYTE $85,"CMOV",'E'+$80 - .WORD W_CLS -C_CMOVE: - .WORD 2+$ ; Vector to code - LD L,C ; Save BC for now - LD H,B ; - POP BC ; Get no. of bytes to move - POP DE ; Get destination address - EX (SP),HL ; Get source address - LD A,B ; Check it's not a 0 length block - OR C ; - JR Z,NO_BYTES ; If 0 length then do nothing - LDIR ; Move block -NO_BYTES: - POP BC ; Get BC back - JP NEXT - -W_USTAR: ; Unsigned multiply - .BYTE $82,"U",'*'+$80 - .WORD W_CMOVE -C_USTAR: - .WORD 2+$ ; Vector to code - POP DE ; get n2 - POP HL ; get n1 - PUSH BC ; save BC for now - LD C,H ; save H - LD A,L ; low byte to multiply by - CALL HALF_TIMES ; HL = A * DE - PUSH HL ; save partial result - LD H,A ; clear H - LD A,C ; high byte to multiply by - LD C,H ; clear B - CALL HALF_TIMES ; HL = A * DE - POP DE ; get last partial result - LD B,C ; add partial results - LD C,D ; add partial results - ADD HL,BC ; - ADC A,$00 ; - LD D,L ; - LD L,H ; - LD H,A ; - POP BC ; get BC back - JP NEXTS2 ; save 32 bit result & NEXT - -HALF_TIMES: ; - LD HL,$0000 ; clear partial result - LD B,08h ; eight bits to do -NEXT_BIT: - ADD HL,HL ; result * 2 - RLA ; multiply bit into C - JR NC,NO_MUL ; branch if no multiply - ADD HL,DE ; add multiplicand - ADC A,$00 ; add in any carry -NO_MUL: - DJNZ NEXT_BIT ; decr and loop if not done - RET ; - -W_UMOD: ; Unsigned divide & MOD - .BYTE $85,"U/MO",'D'+$80 - .WORD W_USTAR -C_UMOD: - .WORD 2+$ ; Vector to code - LD HL,0004 - ADD HL,SP - LD E,(HL) - LD (HL),C - INC HL - LD D,(HL) - LD (HL),B - POP BC - POP HL - LD A,L - SUB C - LD A,H - SBC A,B - JR C,J22DB - LD HL,$FFFF - LD DE,$FFFF - JR J2301 -J22DB: - LD A,10h -J22DD: - ADD HL,HL - RLA - EX DE,HL - ADD HL,HL - JR NC,J22E5 - INC DE - AND A -J22E5: - EX DE,HL - RRA - PUSH AF - JR NC,J22F2 - LD A,L - SUB C - LD L,A - LD A,H - SBC A,B - LD H,A - JR J22FC -J22F2: - LD A,L - SUB C - LD L,A - LD A,H - SBC A,B - LD H,A - JR NC,J22FC - ADD HL,BC - DEC DE -J22FC: - INC DE - POP AF - DEC A - JR NZ,J22DD -J2301: - POP BC - PUSH HL - PUSH DE - JP NEXT - -W_AND: ; AND - .BYTE $83,"AN",'D'+$80 - .WORD W_UMOD -C_AND: - .WORD 2+$ ; Vector to code - POP DE ; Get n1 off stack - POP HL ; Get n2 off stack - LD A,E ; AND lo bytes - AND L ; - LD L,A ; Result in L - LD A,D ; AND hi bytes - AND H ; - LD H,A ; Result in H - JP NEXTS1 ; Save & next - -W_OR: ; OR - .BYTE $82,"O",'R'+$80 - .WORD W_AND -C_OR: - .WORD 2+$ ; Vector to code - POP DE ; Get n1 off stack - POP HL ; Get n2 off stack - LD A,E ; OR lo bytes - OR L ; - LD L,A ; Result in L - LD A,D ; OR hi bytes - OR H ; - LD H,A ; Result in H - JP NEXTS1 ; Save & next - -W_XOR: ; XOR - .BYTE $83,"XO",'R'+$80 - .WORD W_OR -C_XOR: - .WORD 2+$ ; Vector to code - POP DE ; Get n1 off stack - POP HL ; Get n2 off stack - LD A,E ; XOR lo bytes - XOR L ; - LD L,A ; Result in L - LD A,D ; XOR hi bytes - XOR H ; - LD H,A ; Result in H - JP NEXTS1 ; Save & NEXT - -W_SPFETCH: ; Stack pointer onto stack - .BYTE $83,"SP",'@'+$80 - .WORD W_XOR -C_SPFETCH: - .WORD 2+$ ; Vector to code - LD HL,0000 ; No offset - ADD HL,SP ; Add SP to HL - JP NEXTS1 ; Save & NEXT - -W_SPSTORE: ; Set initial stack pointer value - .BYTE $83,"SP",'!'+$80 - .WORD W_SPFETCH -C_SPSTORE: - .WORD 2+$ ; Vector to code - LD HL,(DEF_SYSADDR) ; Get system base addr - LD DE,S0-SYSTEM ; Offset to stack pointer value (0006) - ADD HL,DE ; Add to base addr - LD E,(HL) ; Get SP from ram - INC HL ; - LD D,(HL) ; - EX DE,HL ; Put into HL - LD SP,HL ; Set SP - JP NEXT - -W_RPFETCH: ; Get return stack pointer - .BYTE $83,"RP",'@'+$80 - .WORD W_SPSTORE -C_RPFETCH: - .WORD 2+$ ; Vector to code - LD HL,(RPP) ; Return stack pointer into HL - JP NEXTS1 ; Save & NEXT - -W_RPSTORE: ; Set initial return stack pointer - .BYTE $83,"RP",'!'+$80 - .WORD W_RPFETCH -C_RPSTORE: - .WORD 2+$ ; Vector to code - LD HL,(DEF_SYSADDR) ; Get system base addr - LD DE,0008 ; Offset to return stack pointer value - ADD HL,DE ; Add to base addr - LD E,(HL) ; Get SP from ram - INC HL ; - LD D,(HL) ; - EX DE,HL ; Put into HL - LD (RPP),HL ; Set return SP - JP NEXT - -W_STOP: ; Pop BC from return stack (=next) - .BYTE $82,"; ",'S'+$80 - .WORD W_RPSTORE -C_STOP: - .WORD 2+$ ; Vector to code -X_STOP: - LD HL,(RPP) ; Return stack pointer to HL - LD C,(HL) ; Get low byte - INC HL ; - LD B,(HL) ; Get high byte - INC HL ; - LD (RPP),HL ; Save stack pointer - JP NEXT - -W_LEAVE: ; Quit loop by making index = limit - .BYTE $85,"LEAV",'E'+$80 - .WORD W_STOP -C_LEAVE: - .WORD 2+$ ; Vector to code - LD HL,(RPP) ; Get return stack pointer - LD E,(HL) ; Get loop limit low - INC HL ; - LD D,(HL) ; Get loop limit high - INC HL ; - LD (HL),E ; Set index low to loop limit - INC HL ; - LD (HL),D ; Set index high to loop limit - JP NEXT - -W_MOVER: ; Move from data to return stack - .BYTE $82,">",'R'+$80 - .WORD W_LEAVE -C_MOVER: - .WORD 2+$ ; Vector to code - POP DE ; Get value - LD HL,(RPP) ; Get return stack pointer - DEC HL ; Set new value - DEC HL ; - LD (RPP),HL ; Save it - LD (HL),E ; Push low byte onto return stack - INC HL ; - LD (HL),D ; Push high byte onto return stack - JP NEXT - -W_RMOVE: ; Move word from return to data stack - .BYTE $82,"R",'>'+$80 - .WORD W_MOVER -C_RMOVE: - .WORD 2+$ ; Vector to code - LD HL,(RPP) ; Get return stack pointer - LD E,(HL) ; Pop word off return stack - INC HL ; - LD D,(HL) ; - INC HL ; - LD (RPP),HL ; Save new return stack pointer - PUSH DE ; Push on data stack - JP NEXT - -W_RFETCH: ; Return stack top to data stack - .BYTE $82,"R",'@'+$80 - .WORD W_RMOVE -C_RFETCH: - .WORD X_I ; Return stack top to data stack - - -W_0EQUALS: ; =0 - .BYTE $82,"0",'='+$80 - .WORD W_RFETCH -C_0EQUALS: - .WORD 2+$ ; Vector to code -X_0EQUALS: - POP HL ; Get value from stack - LD A,L ; set flags - OR H ; - LD HL,0000 ; Not = 0 flag - JR NZ,NO_ZERO ; - INC HL ; = 0 flag -NO_ZERO: - JP NEXTS1 ; Save & NEXT - -W_NOT: ; Convert flag, same as 0= - .BYTE $83,"NO",'T'+$80 - .WORD W_0EQUALS -C_NOT: - .WORD X_0EQUALS - -W_0LESS: ; Less than 0 - .BYTE $82,"0",'<'+$80 - .WORD W_NOT -C_0LESS: - .WORD 2+$ ; Vector to code - POP HL ; Get value - ADD HL,HL ; S bit into C - LD HL,0000 ; Wasn't < 0 flag - JR NC,NOT_LT0 ; - INC HL ; Was < 0 flag -NOT_LT0: JP NEXTS1 ; Save & NEXT - -W_PLUS: ; n1 + n2 - .BYTE $81,'+'+$80 - .WORD W_0LESS -C_PLUS: - .WORD 2+$ ; Vector to code - POP DE ; Get n2 - POP HL ; Get n1 - ADD HL,DE ; Add them - JP NEXTS1 ; Save & NEXT - -W_DPLUS: ; 32 bit add - .BYTE $82,"D",'+'+$80 - .WORD W_PLUS -C_DPLUS: - .WORD 2+$ ; Vector to code - LD HL,0006 ; offset to low word - ADD HL,SP ; add stack pointer - LD E,(HL) ; get d1 low word low byte - LD (HL),C ; save BC low byte - INC HL ; point to high byte - LD D,(HL) ; get d1 low word high byte - LD (HL),B ; save BC high byte - POP BC ; get high word d2 - POP HL ; get low word d2 - ADD HL,DE ; add low words - EX DE,HL ; save result low word in DE - POP HL ; get d1 high word - LD A,L ; copy d1 high word low byte - ADC A,C ; add d2 high word low byte - ; + carry from low word add - LD L,A ; result from high word low byte into L - LD A,H ; copy d1 high word low byte - ADC A,B ; add d2 high word low byte - ; + carry from high word low byte add - LD H,A ; result from high word high byte into H - POP BC ; restore BC - JP NEXTS2 ; Save 32 bit result & NEXT - -W_NEGATE: ; Form 2s complement of n - .BYTE $86,"NEGAT",'E'+$80 - .WORD W_DPLUS -C_NEGATE: - .WORD 2+$ ; Vector to code - POP HL ; Get number - LD A,L ; Low byte into A - CPL ; Complement it - LD L,A ; Back into L - LD A,H ; High byte into A - CPL ; Complement it - LD H,A ; Back into H - INC HL ; +1 - JP NEXTS1 ; Save & NEXT - -W_DNEGATE: ; Form 2s complement of 32 bit n - .BYTE $87,"DNEGAT",'E'+$80 - .WORD W_NEGATE -C_DNEGATE: - .WORD 2+$ ; Vector to code - POP HL ; get high word - POP DE ; get low word - SUB A ; clear A - SUB E ; negate low word low byte - LD E,A ; copy back to E - LD A,$00 ; clear A - SBC A,D ; negate low word high byte - LD D,A ; copy back to D - LD A,$00 ; clear A - SBC A,L ; negate high word low byte - LD L,A ; copy back to L - LD A,$00 ; clear A - SBC A,H ; negate high word high byte - LD H,A ; copy back to H - JP NEXTS2 ; Save 32 bit result & NEXT - -W_OVER: ; Copy 2nd down to top of stack - .BYTE $84,"OVE",'R'+$80 - .WORD W_DNEGATE -C_OVER: - .WORD 2+$ ; Vector to code - POP DE ; Get top - POP HL ; Get next - PUSH HL ; Save it back - JP NEXTS2 ; Save both & NEXT - -W_DROP: ; Drop top value from stack - .BYTE $84,"DRO",'P'+$80 - .WORD W_OVER -C_DROP: - .WORD 2+$ ; Vector to code - POP HL ; Get top value - JP NEXT - -W_2DROP: ; Drop top two values from stack - .BYTE $85,"2DRO",'P'+$80 - .WORD W_DROP -C_2DROP: - .WORD 2+$ ; Vector to code - POP HL ; Get top value - POP HL ; Get top value - JP NEXT - -W_SWAP: ; Swap top 2 values on stack - .BYTE $84,"SWA",'P'+$80 - .WORD W_2DROP -C_SWAP: - .WORD 2+$ ; Vector to code - POP HL ; Get top value - EX (SP),HL ; Exchanhe with next down - JP NEXTS1 ; Save & NEXT - -W_DUP: ; Duplicate top value on stack - .BYTE $83,"DU",'P'+$80 - .WORD W_SWAP -C_DUP: - .WORD 2+$ ; Vector to code - POP HL ; Get value off stack - PUSH HL ; Copy it back - JP NEXTS1 ; Save & NEXT - -W_2DUP: ; Dup top 2 values on stack - .BYTE $84,"2DU",'P'+$80 - .WORD W_DUP -C_2DUP: - .WORD 2+$ ; Vector to code - POP HL ; Get top two values from stack - POP DE ; - PUSH DE ; Copy them back - PUSH HL ; - JP NEXTS2 ; Save both & NEXT - -W_BOUNDS: ; Convert address & n to start & end - .BYTE $86,"BOUND",'S'+$80 - .WORD W_2DUP -C_BOUNDS: - .WORD 2+$ ; Vector to code - POP HL ; get n - POP DE ; get addr - ADD HL,DE ; add addr to n - EX DE,HL ; swap them - JP NEXTS2 ; save both & NEXT - -W_PLUSSTORE: ; Add n1 to addr - .BYTE $82,"+",'!'+$80 - .WORD W_BOUNDS -C_PLUSSTORE: - .WORD 2+$ ; Vector to code - POP HL ; Get addr - POP DE ; Get DE - LD A,(HL) ; Add low bytes - ADD A,E ; - LD (HL),A ; Store result - INC HL ; Point to high byte - LD A,(HL) ; Add high bytes - ADC A,D ; - LD (HL),A ; Store result - JP NEXT - -W_TOGGLE: ; XOR (addr) with byte - .BYTE $86,"TOGGL",'E'+$80 - .WORD W_PLUSSTORE -C_TOGGLE: - .WORD 2+$ ; Vector to code - POP DE ; Get byte - POP HL ; Get addr - LD A,(HL) ; Get byte from addr - XOR E ; Toggle it - LD (HL),A ; Save result - JP NEXT - -W_FETCH: ; Get word from addr on stack - .BYTE $81,'@'+$80 - .WORD W_TOGGLE -C_FETCH: - .WORD 2+$ ; Vector to code - POP HL ; Get addr - LD E,(HL) ; Get low byte - INC HL ; - LD D,(HL) ; Get high byte - PUSH DE ; Save it - JP NEXT - -W_CFETCH: ; Get byte from addr on stack - .BYTE $82,"C",'@'+$80 - .WORD W_FETCH -C_CFETCH: - .WORD 2+$ ; Vector to code - POP HL ; Get addr - LD L,(HL) ; Get byte - LD H,$00 ; Top byte = 0 - JP NEXTS1 ; Save & NEXT - -W_2FETCH: ; Get word from addr+2 and addr - .BYTE $82,"2",'@'+$80 - .WORD W_CFETCH -C_2FETCH: - .WORD 2+$ ; Vector to code - POP HL ; Get addr - LD DE,0002 ; Plus 2 bytes - ADD HL,DE ; Get 2nd word first - LD E,(HL) ; Low byte - INC HL ; - LD D,(HL) ; High byte - PUSH DE ; Save it - LD DE,$FFFD ; Minus 2 bytes - ADD HL,DE ; Get 1st word - LD E,(HL) ; Low byte - INC HL ; - LD D,(HL) ; High byte - PUSH DE ; Save it - JP NEXT - -W_STORE: ; Store word at addr - .BYTE $81,'!'+$80 - .WORD W_2FETCH -C_STORE: - .WORD 2+$ ; Vector to code - POP HL ; Get addr - POP DE ; Get word - LD (HL),E ; Store low byte - INC HL ; - LD (HL),D ; Store high byte - JP NEXT - -W_CSTORE: ; Store byte at addr - .BYTE $82,"C",'!'+$80 - .WORD W_STORE -C_CSTORE: - .WORD 2+$ ; Vector to code - POP HL ; Get addr - POP DE ; Get byte - LD (HL),E ; Save it - JP NEXT - -W_2STORE: ; Store 2 words at addr (+2) - .BYTE $82,"2",'!'+$80 - .WORD W_CSTORE -C_2STORE: - .WORD 2+$ ; Vector to code - POP HL ; Get addr - POP DE ; Get word - LD (HL),E ; Save low byte - INC HL ; - LD (HL),D ; Save high byte - INC HL ; - POP DE ; Get next word - LD (HL),E ; Save low byte - INC HL ; - LD (HL),D ; Save high byte - JP NEXT - -W_COLON: - .BYTE $81,':'+$80 - .WORD W_2STORE -C_COLON: - .WORD E_COLON ; Interpret following word sequence - .WORD C_QEXEC ; Error not if not in execute mode - .WORD C_CSPSTORE ; Set current stack pointer value - .WORD C_CURRENT ; Get CURRENT addr - .WORD C_FETCH ; Get word from addr on stack - .WORD C_CONTEXT ; Make CONTEXT current vocab - .WORD C_STORE ; Store word at addr - .WORD C_XXX1 ; Puts name into dictionary - .WORD C_RIGHTBRKT ; Set STATE to compile - .WORD C_CCODE ; Execute following machine code - -E_COLON: - LD HL,(RPP) ; Get return stack pointer - DEC HL ; Put BC on return stack - LD (HL),B ; - DEC HL ; - LD (HL),C ; - LD (RPP),HL ; Save new pointer - INC DE - LD C,E - LD B,D - JP NEXT - -W_SEMICOLON: ; Terminate compilation - .BYTE $C1,'; '+$80 - .WORD W_COLON -C_SEMICOLON: - .WORD E_COLON ; Interpret following word sequence - .WORD C_QCOMP ; Check we're allready compiling - .WORD C_WHATSTACK ; Check stack pointer, error if not ok - .WORD C_COMPILE ; Compile next word into dictionary - .WORD C_STOP ; - .WORD C_SMUDGE ; Smudge bit to O.K. - .WORD C_LEFTBRKT ; Set STATE to execute - .WORD C_STOP ; Pop BC from return stack (=next) - -W_CONSTANT: - .BYTE $88,"CONSTAN",'T'+$80 - .WORD W_SEMICOLON -C_CONSTANT: - .WORD E_COLON ; Interpret following word sequence - .WORD C_XXX1 - .WORD C_SMUDGE - .WORD C_COMMA ; Reserve 2 bytes and save n - .WORD C_CCODE ; Execute following machine code - -X_CONSTANT: ; Put next word on stack - INC DE ; Adjust pointer - EX DE,HL ; Get next word - LD E,(HL) ; - INC HL ; - LD D,(HL) ; - PUSH DE ; Put on stack - JP NEXT - -W_VARIABLE: - .BYTE $88,"VARIABL",'E'+$80 - .WORD W_CONSTANT -C_VARIABLE: - .WORD E_COLON ; Interpret following word sequence - .WORD C_ZERO ; Put zero on stack - .WORD C_CONSTANT - .WORD C_CCODE ; Execute following machine code - -X_VARIABLE: - INC DE - PUSH DE - JP NEXT - -W_USER: - .BYTE $84,"USE",'R'+$80 - .WORD W_VARIABLE -C_USER: - .WORD E_COLON ; Interpret following word sequence - .WORD C_CONSTANT - .WORD C_CCODE ; Execute following machine code - -X_USER: - INC DE ; Adjust to next word - EX DE,HL - LD E,(HL) - INC HL - LD D,(HL) - LD HL,(DEF_SYSADDR) - ADD HL,DE - JP NEXTS1 ; Save & NEXT - -W_ZERO: ; Put zero on stack - .BYTE $81,'0'+$80 - .WORD W_USER -C_ZERO: - .WORD X_CONSTANT ; Put next word on stack - .WORD $0000 - -W_1: ; Put 1 on stack - .BYTE $81,'1'+$80 - .WORD W_ZERO -C_1: - .WORD X_CONSTANT ; Put next word on stack - .WORD 0001h - -W_2: - .BYTE $81,'2'+$80 - .WORD W_1 -C_2: - .WORD X_CONSTANT ; Put next word on stack - .WORD 0002h - -W_3: - .BYTE $81,'3'+$80 - .WORD W_2 -C_3: - .WORD X_CONSTANT ; Put next word on stack - .WORD 0003h - -W_BL: ; Leaves ASCII for blank on stack - .BYTE $82,"B",'L'+$80 - .WORD W_3 -C_BL: - .WORD X_CONSTANT ; Put next word on stack - .WORD 0020h - -W_CL: - .BYTE $83,"C/",'L'+$80 - .WORD W_BL -C_CL: - .WORD E_COLON ; Interpret following word sequence - .WORD C_UCL - .WORD C_FETCH ; Get word from addr on stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_FIRST: - .BYTE $85,"FIRS",'T'+$80 - .WORD W_CL -C_FIRST: - .WORD E_COLON ; Interpret following word sequence - .WORD C_UFIRST ; Put UFIRST addr on stack - .WORD C_FETCH ; Get word from addr on stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_LIMIT: - .BYTE $85,"LIMI",'T'+$80 - .WORD W_FIRST -C_LIMIT: - .WORD E_COLON ; Interpret following word sequence - .WORD C_ULIMIT ; Put ULIMIT on stack - .WORD C_FETCH ; Get word from addr on stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_BBUF: - .BYTE $85,"B/BU",'F'+$80 - .WORD W_LIMIT -C_BBUF: - .WORD E_COLON ; Interpret following word sequence - .WORD C_UBBUF - .WORD C_FETCH ; Get word from addr on stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_BSCR: - .BYTE $85,"B/SC",'R'+$80 - .WORD W_BBUF -C_BSCR: - .WORD E_COLON ; Interpret following word sequence - .WORD C_UBSCR ; Number of buffers per block - .WORD C_FETCH ; Get word from addr on stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_S0: ; Push S0 (initial data stack pointer) - .BYTE $82,"S",'0'+$80 - .WORD W_BSCR -C_S0: - .WORD X_USER ; Put next word on stack then do next - .WORD S0-SYSTEM - -W_R0: - .BYTE $82,"R",'0'+$80 - .WORD W_S0 -C_R0: - .WORD X_USER ; Put next word on stack then do next - .WORD R0-SYSTEM - -W_TIB: - .BYTE $83,"TI",'B'+$80 - .WORD W_R0 -C_TIB: - .WORD X_USER ; Put next word on stack then do next - .WORD TIB-SYSTEM - -W_WIDTH: - .BYTE $85,"WIDT",'H'+$80 - .WORD W_TIB -C_WIDTH: - .WORD X_USER ; Put next word on stack then do next - .WORD WIDTH-SYSTEM - -W_WARNING: ; Put WARNING addr on stack - .BYTE $87,"WARNIN",'G'+$80 - .WORD W_WIDTH -C_WARNING: - .WORD X_USER ; Put next word on stack then do next - .WORD WARNING-SYSTEM - -W_FENCE: - .BYTE $85,"FENC",'E'+$80 - .WORD W_WARNING -C_FENCE: - .WORD X_USER ; Put next word on stack then do next - .WORD FENCE-SYSTEM - -W_DP: ; Dictionary pointer addr on stack - .BYTE $82,"D",'P'+$80 - .WORD W_FENCE -C_DP: - .WORD X_USER ; Put next word on stack then do next - .WORD DP-SYSTEM - -W_VOC_LINK: - .BYTE $88,"VOC-LIN",'K'+$80 - .WORD W_DP -C_VOC_LINK: - .WORD X_USER ; Put next word on stack then do next - .WORD VOC_LINK-SYSTEM - -W_BLK: - .BYTE $83,"BL",'K'+$80 - .WORD W_VOC_LINK -C_BLK: - .WORD X_USER ; Put next word on stack then do next - .WORD BLK-SYSTEM - -W_TOIN: - .BYTE $83,">I",'N'+$80 - .WORD W_BLK -C_TOIN: - .WORD X_USER ; Put next word on stack then do next - .WORD TOIN-SYSTEM - -W_OUT: ; Put OUT buffer count addr on stack - .BYTE $83,"OU",'T'+$80 - .WORD W_TOIN -C_OUT: - .WORD X_USER ; Put next word on stack then do next - .WORD OUT-SYSTEM - -W_SCR: - .BYTE $83,"SC",'R'+$80 - .WORD W_OUT -C_SCR: - .WORD X_USER ; Put next word on stack then do next - .WORD SCR-SYSTEM - -W_OFFSET: ; Put disk block offset on stack - .BYTE $86,"OFFSE",'T'+$80 - .WORD W_SCR -C_OFFSET: - .WORD X_USER ; Put next word on stack then do next - .WORD OFFSET-SYSTEM - -W_CONTEXT: - .BYTE $87,"CONTEX",'T'+$80 - .WORD W_OFFSET -C_CONTEXT: - .WORD X_USER ; Put next word on stack then do next - .WORD CONTEXT-SYSTEM - -W_CURRENT: - .BYTE $87,"CURREN",'T'+$80 - .WORD W_CONTEXT -C_CURRENT: - .WORD X_USER ; Put next word on stack then do next - .WORD CURRENT-SYSTEM - -W_STATE: ; Push STATE addr - .BYTE $85,"STAT",'E'+$80 - .WORD W_CURRENT -C_STATE: - .WORD X_USER ; Put next word on stack then do next - .WORD STATE-SYSTEM - -W_BASE: ; Put BASE addr on stack - .BYTE $84,"BAS",'E'+$80 - .WORD W_STATE -C_BASE: - .WORD X_USER ; Put next word on stack then do next - .WORD BASE-SYSTEM - -W_DPL: - .BYTE $83,"DP",'L'+$80 - .WORD W_BASE -C_DPL: - .WORD X_USER ; Put next word on stack then do next - .WORD DPL-SYSTEM - -W_FLD: - .BYTE $83,"FL",'D'+$80 - .WORD W_DPL -C_FLD: - .WORD X_USER ; Put next word on stack then do next - .WORD FLD-SYSTEM - -W_CSP: ; Push check stack pointer addr - .BYTE $83,"CS",'P'+$80 - .WORD W_FLD -C_CSP: - .WORD X_USER ; Put next word on stack then do next - .WORD CSP-SYSTEM - -W_RHASH: - .BYTE $82,"R",'#'+$80 - .WORD W_CSP -C_RHASH: - .WORD X_USER ; Put next word on stack then do next - .WORD RHASH-SYSTEM - -W_HLD: - .BYTE $83,"HL",'D'+$80 - .WORD W_RHASH -C_HLD: - .WORD X_USER ; Put next word on stack then do next - .WORD HLD-SYSTEM - -W_UCL: - .BYTE $84,"UC/",'L'+$80 - .WORD W_HLD -C_UCL: - .WORD X_USER ; Put next word on stack then do next - .WORD UCL-SYSTEM - -W_UFIRST: - .BYTE $86,"UFIRS",'T'+$80 - .WORD W_UCL -C_UFIRST: - .WORD X_USER ; Put next word on stack then do next - .WORD UFIRST-SYSTEM - -W_ULIMIT: - .BYTE $86,"ULIMI",'T'+$80 - .WORD W_UFIRST -C_ULIMIT: - .WORD X_USER ; Put next word on stack then do next - .WORD ULIMIT-SYSTEM - -W_UBBUF: - .BYTE $86,"UB/BU",'F'+$80 - .WORD W_ULIMIT -C_UBBUF: - .WORD X_USER ; Put next word on stack then do next - .WORD UBBUF-SYSTEM - -W_UBSCR: - .BYTE $86,"UB/SC",'R'+$80 - .WORD W_UBBUF -C_UBSCR: - .WORD X_USER ; Put next word on stack then do next - .WORD UBSCR-SYSTEM - -W_UTERMINAL: - .BYTE 8Ah,"U?TERMINA",'L'+$80 - .WORD W_UBSCR -C_UTERMINAL: - .WORD X_USER ; Put next word on stack then do next - .WORD UTERMNL-SYSTEM - -W_UKEY: ; Put UKEY addr on stack - .BYTE $84,"UKE",'Y'+$80 - .WORD W_UTERMINAL -C_UKEY: - .WORD X_USER ; Put next word on stack then do next - .WORD UKEY-SYSTEM - -W_UEMIT: ; Put UEMIT addr on stack - .BYTE $85,"UEMI",'T'+$80 - .WORD W_UKEY -C_UEMIT: - .WORD X_USER ; Put next word on stack then do next - .WORD UEMIT-SYSTEM - -W_UCR: ; Push UCR addr - .BYTE $83,"UC",'R'+$80 - .WORD W_UEMIT -C_UCR: - .WORD X_USER ; Put next word on stack then do next - .WORD UCR-SYSTEM - -W_URW: - .BYTE $84,"UR/",'W'+$80 - .WORD W_UCR -C_URW: - .WORD X_USER ; Put next word on stack then do next - .WORD URW-SYSTEM - -W_UABORT: ; Put UABORT on stack - .BYTE $86,"UABOR",'T'+$80 - .WORD W_URW -C_UABORT: - .WORD X_USER ; Put next word on stack then do next - .WORD UABORT-SYSTEM - -W_RAF: - .BYTE $83,"RA",'F'+$80 - .WORD W_UABORT -C_RAF: - .WORD X_USER ; Put next word on stack then do next - .WORD RAF-SYSTEM - -W_RBC: - .BYTE $83,"RB",'C'+$80 - .WORD W_RAF -C_RBC: - .WORD X_USER ; Put next word on stack then do next - .WORD RBC-SYSTEM - -W_RDE: - .BYTE $83,"RD",'E'+$80 - .WORD W_RBC -C_RDE - .WORD X_USER ; Put next word on stack then do next - .WORD RDE-SYSTEM - -W_RHL: - .BYTE $83,"RH",'L'+$80 - .WORD W_RDE -C_RHL: - .WORD X_USER ; Put next word on stack then do next - .WORD RHL-SYSTEM - -W_RIX: - .BYTE $83,"RI",'X'+$80 - .WORD W_RHL -C_RIX: - .WORD X_USER ; Put next word on stack then do next - .WORD RIX-SYSTEM - -W_RIY: - .BYTE $83,"RI",'Y'+$80 - .WORD W_RIX -C_RIY: - .WORD X_USER ; Put next word on stack then do next - .WORD RIY-SYSTEM - -W_RAF2: - .BYTE $84,"RAF",2Ch+$80 - .WORD W_RIY -C_RAF2: - .WORD X_USER ; Put next word on stack then do next - .WORD RAF2-SYSTEM - -W_RBC2: - .BYTE $84,"RBC",2Ch+$80 - .WORD W_RAF2 -C_RBC2: - .WORD X_USER ; Put next word on stack then do next - .WORD RBC2-SYSTEM - -W_RDE2: - .BYTE $84,"RDE",2Ch+$80 - .WORD W_RBC2 -C_RDE2: - .WORD X_USER ; Put next word on stack then do next - .WORD RDE2-SYSTEM - -W_RHL2: - .BYTE $84,"RHL",2Ch+$80 - .WORD W_RDE2 -C_RHL2: - .WORD X_USER ; Put next word on stack then do next - .WORD RHL2-SYSTEM - -W_RA: - .BYTE $82,"R",'A'+$80 - .WORD W_RHL2 -C_RA: - .WORD X_USER ; Put next word on stack then do next - .WORD RAF+1-SYSTEM - -W_RF: - .BYTE $82,"R",'F'+$80 - .WORD W_RA -C_RF: - .WORD X_USER ; Put next word on stack then do next - .WORD RAF-SYSTEM - -W_RB: - .BYTE $82,"R",'B'+$80 - .WORD W_RF -C_RB: - .WORD X_USER ; Put next word on stack then do next - .WORD RBC+1-SYSTEM - -W_RC: - .BYTE $82,"R",'C'+$80 - .WORD W_RB -C_RC: - .WORD X_USER ; Put next word on stack then do next - .WORD RBC-SYSTEM - -W_RD: - .BYTE $82,"R",'D'+$80 - .WORD W_RC -C_RD: - .WORD X_USER ; Put next word on stack then do next - .WORD RDE+1-SYSTEM - -W_RE: - .BYTE $82,"R",'E'+$80 - .WORD W_RD -C_RE: - .WORD X_USER ; Put next word on stack then do next - .WORD RDE-SYSTEM - -W_RH: - .BYTE $82,"R",'H'+$80 - .WORD W_RE -C_RH: - .WORD X_USER ; Put next word on stack then do next - .WORD RHL+1-SYSTEM - -W_RL: - .BYTE $82,"R",'L'+$80 - .WORD W_RH -C_RL: - .WORD X_USER ; Put next word on stack then do next - .WORD RHL-SYSTEM - -W_CALL: - .BYTE $84,"CAL",'L'+$80 - .WORD W_RL -C_CALL: - .WORD 2+$ ; Vector to code - POP HL ; Address of routine CALLed - PUSH DE ; Save register - PUSH BC ; Save register - LD A,$C3 ; Hex code for JMP - LD (JPCODE),A ; Save it - LD (JPVECT),HL ; Save jump vector - LD HL,(RAF) ; Get register AF - PUSH HL ; Onto stack - POP AF ; POP into AF - LD BC,(RBC) ; Get register BC - LD DE,(RDE) ; Get register DE - LD HL,(RHL) ; Get register HL - LD IX,(RIX) ; Get register IX - LD IY,(RIY) ; Get register IY - CALL JPCODE ; Call jump to code - LD (RIY),IY ; Save register IY - LD (RIX),IX ; Save register IX - LD (RBC),BC ; Save register BC - LD (RDE),DE ; Save register DE - LD (RHL),HL ; Save register HL - PUSH AF ; Save register AF - POP HL ; Into HL - LD (RAF),HL ; Into memory - POP BC ; Restore BC - POP DE ; Restore DE - JP NEXT ; - -W_1PLUS: ; 1 plus - .BYTE $82,"1",'+'+$80 - .WORD W_CALL -C_1PLUS: - .WORD 2+$ ; Vector to code - POP HL ; get n - INC HL ; add 1 - JP NEXTS1 ; save result & NEXT - -W_2PLUS: ; 2 plus - .BYTE $82,"2",'+'+$80 - .WORD W_1PLUS -C_2PLUS: - .WORD 2+$ ; Vector to code - POP HL ; get n - INC HL ; add 1 - INC HL ; add 2 - JP NEXTS1 ; save result & NEXT - -W_1MINUS: ; 1 minus - .BYTE $82,"1",'-'+$80 - .WORD W_2PLUS -C_1MINUS: - .WORD 2+$ ; Vector to code - POP HL ; get n - DEC HL ; add 1 - JP NEXTS1 ; save result & NEXT - -W_2MINUS: ; 2 minus - .BYTE $82,"2",'-'+$80 - .WORD W_1MINUS -C_2MINUS: - .WORD 2+$ ; Vector to code - POP HL ; get n - DEC HL ; subtract 1 - DEC HL ; subtract 2 - JP NEXTS1 ; save result & NEXT - -W_HERE: ; Dictionary pointer onto stack - .BYTE $84,"HER",'E'+$80 - .WORD W_2MINUS -C_HERE: - .WORD E_COLON ; Interpret following word sequence - .WORD C_DP ; Dictionary pointer addr on stack - .WORD C_FETCH ; Get word from addr on stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_ALLOT: - .BYTE $85,"ALLO",'T'+$80 - .WORD W_HERE -C_ALLOT: - .WORD E_COLON ; Interpret following word sequence - .WORD C_DP ; Dictionary pointer addr on stack - .WORD C_PLUSSTORE ; Add n1 to addr - .WORD C_STOP ; Pop BC from return stack (=next) - -W_COMMA: ; Reserve 2 bytes and save n - .BYTE $81,','+$80 - .WORD W_ALLOT -C_COMMA: - .WORD E_COLON ; Interpret following word sequence - .WORD C_HERE ; Next free dictionary pointer onto stack - .WORD C_STORE ; Store word at addr - .WORD C_2 ; - .WORD C_ALLOT ; Move pointer - .WORD C_STOP ; Pop BC from return stack (=next) - -W_CCOMMA: - .BYTE $82,"C",','+$80 - .WORD W_COMMA -C_CCOMMA: - .WORD E_COLON ; Interpret following word sequence - .WORD C_HERE ; Dictionary pointer onto stack - .WORD C_CSTORE ; Store byte at addr - .WORD C_1 ; Put 1 on stack - .WORD C_ALLOT - .WORD C_STOP ; Pop BC from return stack (=next) - -W_MINUS: - .BYTE $81,'-'+$80 - .WORD W_CCOMMA -C_MINUS: - .WORD 2+$ ; Vector to code - POP DE ; get n1 - POP HL ; get n2 - CALL MINUS16 ; call subtract routine - JP NEXTS1 ; save & NEXT - -MINUS16: - LD A,L ; gel low byte - SUB E ; subtract low bytes - LD L,A ; save low byte result - LD A,H ; get high byte - SBC A,D ; subtract high bytes - LD H,A ; save high byte result - RET ; - -W_EQUALS: - .BYTE $81,'='+$80 - .WORD W_MINUS -C_EQUALS: - .WORD E_COLON ; Interpret following word sequence - .WORD C_MINUS - .WORD C_0EQUALS ; =0 - .WORD C_STOP ; Pop BC from return stack (=next) - -W_LESSTHAN: - .BYTE $81,'<'+$80 - .WORD W_EQUALS -C_LESSTHAN: - .WORD 2+$ ; Vector to code - POP DE - POP HL - LD A,D - XOR H - JP M,J298C - CALL MINUS16 -J298C: - INC H - DEC H - JP M,J2997 - LD HL,0000 - JP NEXTS1 ; Save & NEXT -J2997: - LD HL,0001 - JP NEXTS1 ; Save & NEXT - -W_ULESS: ; IF stack-1 < stack_top leave true flag - .BYTE $82,"U",'<'+$80 - .WORD W_LESSTHAN -C_ULESS: - .WORD E_COLON ; Interpret following word sequence - .WORD C_2DUP ; Dup top 2 values on stack - .WORD C_XOR ; Exclusive OR them - .WORD C_0LESS ; Less than 0 - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B0000-$ ; 000Ch - .WORD C_DROP ; Drop top value from stack - .WORD C_0LESS ; Less than 0 - .WORD C_0EQUALS ; =0 - .WORD C_BRANCH ; Add following offset to BC - .WORD B0001-$ ; 0006h -B0000: - .WORD C_MINUS - .WORD C_0LESS ; Less than 0 -B0001: - .WORD C_STOP ; Pop BC from return stack (=next) - -W_GREATER: - .BYTE $81,'>'+$80 - .WORD W_ULESS -C_GREATER: - .WORD E_COLON ; Interpret following word sequence - .WORD C_SWAP ; Swap top 2 values on stack - .WORD C_LESSTHAN - .WORD C_STOP ; Pop BC from return stack (=next) - -W_ROT: ; 3rd valu down to top of stack - .BYTE $83,"RO",'T'+$80 - .WORD W_GREATER -C_ROT: - .WORD 2+$ ; Vector to code - POP DE ; Top value - POP HL ; Next one down - EX (SP),HL ; Exchange with third - JP NEXTS2 ; Save both & NEXT - -W_PICK: - .BYTE $84,"PIC",'K'+$80 - .WORD W_ROT -C_PICK: - .WORD E_COLON ; Interpret following word sequence - .WORD C_DUP ; Duplicate top value on stack - .WORD C_PLUS ; n1 + n2 - .WORD C_SPFETCH ; Stack pointer onto stack - .WORD C_PLUS ; n1 + n2 - .WORD C_FETCH ; Get word from addr on stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_SPACE: - .BYTE $85,"SPAC",'E'+$80 - .WORD W_PICK -C_SPACE: - .WORD E_COLON ; Interpret following word sequence - .WORD C_BL ; Leaves ASCII for space on stack - .WORD C_EMIT ; Output CHR from stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_QUERYDUP: - .BYTE $84,"?DU",'P'+$80 - .WORD W_SPACE -C_QUERYDUP: - .WORD E_COLON ; Interpret following word sequence - .WORD C_DUP ; Duplicate top value on stack - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B0002-$ ; 0004h - .WORD C_DUP ; Duplicate top value on stack -B0002: - .WORD C_STOP ; Pop BC from return stack (=next) - -W_TRAVERSE: - .BYTE $88,"TRAVERS",'E'+$80 - .WORD W_QUERYDUP -C_TRAVERSE: - .WORD E_COLON ; Interpret following word sequence - .WORD C_SWAP ; Swap top 2 values on stack -B0054: - .WORD C_OVER ; Copy 2nd down to top of stack - .WORD C_PLUS ; n1 + n2 - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 007Fh - .WORD C_OVER ; Copy 2nd down to top of stack - .WORD C_CFETCH ; Get byte from addr on stack - .WORD C_LESSTHAN - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B0054-$ ; FFF0h - .WORD C_SWAP ; Swap top 2 values on stack - .WORD C_DROP ; Drop top value from stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_LATEST: - .BYTE $86,"LATES",'T'+$80 - .WORD W_TRAVERSE -C_LATEST: - .WORD E_COLON ; Interpret following word sequence - .WORD C_CURRENT - .WORD C_FETCH ; Get word from addr on stack - .WORD C_FETCH ; Get word from addr on stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_LFA: - .BYTE $83,"LF",'A'+$80 - .WORD W_LATEST -C_LFA: - .WORD E_COLON ; Interpret following word sequence - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 0004h - .WORD C_MINUS - .WORD C_STOP ; Pop BC from return stack (=next) - -W_CFA: - .BYTE $83,"CF",'A'+$80 - .WORD W_LFA -C_CFA: - .WORD 2+$ ; Vector to code - POP HL ; get n - DEC HL ; subtract 1 - DEC HL ; subtract 2 - JP NEXTS1 ; save result & NEXT -W_NFA: - .BYTE $83,"NF",'A'+$80 - .WORD W_CFA -C_NFA: - .WORD E_COLON ; Interpret following word sequence - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 0005h - .WORD C_MINUS - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD $FFFF - .WORD C_TRAVERSE - .WORD C_STOP ; Pop BC from return stack (=next) - -W_PFA: ; Convert NFA to PFA - .BYTE $83,"PF",'A'+$80 - .WORD W_NFA -C_PFA: - .WORD E_COLON ; Interpret following word sequence - .WORD C_1 ; Traverse up memory - .WORD C_TRAVERSE ; End of name on stack - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 0005h ; Offset to start of word code - .WORD C_PLUS ; n1 + n2 - .WORD C_STOP ; Pop BC from return stack (=next) - -W_CSPSTORE: - .BYTE $84,"!CS",'P'+$80 - .WORD W_PFA -C_CSPSTORE: - .WORD E_COLON ; Interpret following word sequence - .WORD C_SPFETCH ; Stack pointer onto stack - .WORD C_CSP ; Push check stack pointer addr - .WORD C_STORE ; Store word at addr - .WORD C_STOP ; Pop BC from return stack (=next) - -W_QERROR: - .BYTE $86,"?ERRO",'R'+$80 - .WORD W_CSPSTORE -C_QERROR: - .WORD E_COLON ; Interpret following word sequence - .WORD C_SWAP ; Swap top 2 values on stack - .WORD C_0BRANCH ; Branch if no error - .WORD B0003-$ ; 0008h - .WORD C_ERROR - .WORD C_BRANCH ; Add following offset to BC - .WORD B0004-$ ; 0004h -B0003: - .WORD C_DROP ; Drop error no. -B0004: - .WORD C_STOP ; Pop BC from return stack (=next) - -W_QCOMP: ; Error if not in compile mode - .BYTE $85,"?COM",'P'+$80 - .WORD W_QERROR -C_QCOMP: - .WORD E_COLON ; Interpret following word sequence - .WORD C_STATE ; Push STATE addr - .WORD C_FETCH ; Get word from addr on stack - .WORD C_0EQUALS ; =0 - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 0011h ; Error message number - .WORD C_QERROR ; Error if state <> 0 - .WORD C_STOP ; Pop BC from return stack (=next) - -W_QEXEC: ; Error not if not in execute mode - .BYTE $85,"?EXE",'C'+$80 - .WORD W_QCOMP -C_QEXEC: - .WORD E_COLON ; Interpret following word sequence - .WORD C_STATE ; Push STATE addr - .WORD C_FETCH ; Get word from addr on stack - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 0012h ; Error not if not in execute mode - .WORD C_QERROR - .WORD C_STOP ; Pop BC from return stack (=next) - -W_QPAIRS: - .BYTE $86,"?PAIR",'S'+$80 - .WORD W_QEXEC -C_QPAIRS: - .WORD E_COLON ; Interpret following word sequence - .WORD C_MINUS - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 0013h - .WORD C_QERROR - .WORD C_STOP ; Pop BC from return stack (=next) - -W_WHATSTACK: ; Check stack pointer, error if not ok - .BYTE $84,"?CS",'P'+$80 - .WORD W_QPAIRS -C_WHATSTACK: - .WORD E_COLON ; Interpret following word sequence - .WORD C_SPFETCH ; Stack pointer onto stack - .WORD C_CSP ; Push check stack pointer addr - .WORD C_FETCH ; Get check stack pointer - .WORD C_MINUS ; If ok then result is 0 - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 0014h ; Error no if not ok - .WORD C_QERROR ; Error if stack top -1 <> 0 - .WORD C_STOP ; Pop BC from return stack (=next) - -W_QLOADING: - .BYTE $88,"?LOADIN",'G'+$80 - .WORD W_WHATSTACK -C_QLOADING: - .WORD E_COLON ; Interpret following word sequence - .WORD C_BLK - .WORD C_FETCH ; Get word from addr on stack - .WORD C_0EQUALS ; =0 - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 0016h - .WORD C_QERROR - .WORD C_STOP ; Pop BC from return stack (=next) - -W_COMPILE: - .BYTE $87,"COMPIL",'E'+$80 - .WORD W_QLOADING -C_COMPILE: - .WORD E_COLON ; Interpret following word sequence - .WORD C_QCOMP ; Error if not in compile mode - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_DUP ; Bump return address and put back - .WORD C_2PLUS ; - .WORD C_MOVER ; - .WORD C_FETCH ; Get word from addr on stack - .WORD C_COMMA ; Reserve 2 bytes and save n - .WORD C_STOP ; Pop BC from return stack (=next) - -W_LEFTBRKT: ; Set STATE to execute - .BYTE $81,'['+$80 - .WORD W_COMPILE -C_LEFTBRKT: - .WORD E_COLON ; Interpret following word sequence - .WORD C_ZERO ; Put zero on stack - .WORD C_STATE ; Push STATE addr - .WORD C_STORE ; Store word at addr - .WORD C_STOP ; Pop BC from return stack (=next) - -W_RIGHTBRKT: ; Set STATE to compile - .BYTE $81,']'+$80 - .WORD W_LEFTBRKT -C_RIGHTBRKT: - .WORD E_COLON ; Interpret following word sequence - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 00$C0 - .WORD C_STATE ; Push STATE addr - .WORD C_STORE ; Set STATE to execute - .WORD C_STOP ; Pop BC from return stack (=next) - -W_SMUDGE: - .BYTE $86,"SMUDG",'E'+$80 - .WORD W_RIGHTBRKT -C_SMUDGE: - .WORD E_COLON ; Interpret following word sequence - .WORD C_LATEST ; Push top words NFA - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 0020h - .WORD C_TOGGLE ; XOR (addr) with byte - .WORD C_STOP ; Pop BC from return stack (=next) - -W_HEX: - .BYTE $83,"HE",'X'+$80 - .WORD W_SMUDGE -C_HEX: - .WORD E_COLON ; Interpret following word sequence - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 0010h - .WORD C_BASE ; Put BASE addr on stack - .WORD C_STORE ; Store word at addr - .WORD C_STOP ; Pop BC from return stack (=next) - -W_DECIMAL: ; Sets decimal mode - .BYTE $87,"DECIMA",'L'+$80 - .WORD W_HEX -C_DECIMAL: - .WORD E_COLON ; Interpret following word sequence - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 00$0A ; Sets decimal value - .WORD C_BASE ; Put BASE addr on stack - .WORD C_STORE ; Store word at addr - .WORD C_STOP ; Pop BC from return stack (=next) - -W_CCODE: ; Stop compillation & terminate word - .BYTE $87,"<; CODE",'>'+$80 - .WORD W_DECIMAL -C_CCODE: - .WORD E_COLON ; Interpret following word sequence - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_LATEST ; Push top words NFA - .WORD C_PFA ; Convert NFA to PFA - .WORD C_CFA ; Convert PFA to CFA - .WORD C_STORE ; Store word at addr - .WORD C_STOP ; Pop BC from return stack (=next) - -W_SCCODE: - .BYTE $C5,"; COD",'E'+$80 - .WORD W_CCODE -C_SCCODE: - .WORD E_COLON ; Interpret following word sequence - .WORD C_WHATSTACK ; Check stack pointer, error if not ok - .WORD C_COMPILE ; Compile next word into dictionary - .WORD C_CCODE - .WORD C_LEFTBRKT ; Set STATE to execute - .WORD C_TASK - .WORD C_STOP ; Pop BC from return stack (=next) - -W_CREATE: - .BYTE $86,"CREAT",'E'+$80 - .WORD W_SCCODE -C_CREATE: - .WORD E_COLON ; Interpret following word sequence - .WORD C_ZERO ; Put zero on stack - .WORD C_CONSTANT - .WORD C_STOP ; Pop BC from return stack (=next) - -W_DOES: - .BYTE $85,"DOES",'>'+$80 - .WORD W_CREATE -C_DOES: - .WORD E_COLON ; Interpret following word sequence - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_LATEST ; Push top words NFA - .WORD C_PFA ; Convert NFA to PFA - .WORD C_STORE ; Store word at addr - .WORD C_CCODE ; Execute following machine code - -X_DOES: - LD HL,(RPP) ; Get return stack pointer - DEC HL ; Push next pointer - LD (HL),B ; - DEC HL ; - LD (HL),C ; - LD (RPP),HL - INC DE - EX DE,HL - LD C,(HL) - INC HL - LD B,(HL) - INC HL - JP NEXTS1 ; Save & NEXT - -W_COUNT: ; Convert string at addr to addr + length - .BYTE $85,"COUN",'T'+$80 - .WORD W_DOES -C_COUNT: - .WORD E_COLON ; Interpret following word sequence - .WORD C_DUP ; Duplicate address - .WORD C_1PLUS ; Add 1 (points to string start) - .WORD C_SWAP ; Get address back - .WORD C_CFETCH ; Get byte from addr on stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_TYPE: ; Output n bytes from addr - .BYTE $84,"TYP",'E'+$80 - .WORD W_COUNT -C_TYPE: - .WORD E_COLON ; Interpret following word sequence - .WORD C_QUERYDUP ; Copy length if length <> 0 - .WORD C_0BRANCH ; Branch if length = 0 - .WORD B0005-$ ; 0018h - .WORD C_OVER ; Copy address to stack top - .WORD C_PLUS ; Add to length - .WORD C_SWAP ; Swap top 2 values on stack - .WORD C_LDO ; Put start & end loop values on RPP -B004F: - .WORD C_I ; Copy LOOP index to data stack - .WORD C_CFETCH ; Get byte from string - .WORD C_EMIT ; Output CHR from stack - .WORD C_LLOOP ; Increment loop & branch if not done - .WORD B004F-$ ; FFF8h - .WORD C_BRANCH ; Done so branch to next - .WORD B0006-$ ; 0004h -B0005: - .WORD C_DROP ; Drop string address -B0006: - .WORD C_STOP ; Pop BC from return stack (=next) - -W_TRAILING: - .BYTE $89,"-TRAILIN",'G'+$80 - .WORD W_TYPE -C_TRAILING: - .WORD E_COLON ; Interpret following word sequence - .WORD C_DUP ; Duplicate top value on stack - .WORD C_ZERO ; Put zero on stack - .WORD C_LDO ; Put start & end loop values on RPP -B0009: - .WORD C_OVER ; Copy 2nd down to top of stack - .WORD C_OVER ; Copy 2nd down to top of stack - .WORD C_PLUS ; n1 + n2 - .WORD C_1 ; Put 1 on stack - .WORD C_MINUS - .WORD C_CFETCH ; Get byte from addr on stack - .WORD C_BL ; Leaves ASCII for space on stack - .WORD C_MINUS - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B0007-$ ; 0008h - .WORD C_LEAVE ; Quit loop by making index = limit - .WORD C_BRANCH ; Add following offset to BC - .WORD B0008-$ ; 0006h -B0007: - .WORD C_1 ; Put 1 on stack - .WORD C_MINUS -B0008: - .WORD C_LLOOP ; Increment loop & branch if not done - .WORD B0009-$ ; FFE0h - .WORD C_STOP ; Pop BC from return stack (=next) - -W_CQUOTE: ; Output following string - .BYTE $84,"<.",22h,'>'+$80 - .WORD W_TRAILING -C_CQUOTE: - .WORD E_COLON ; Interpret following word sequence - .WORD C_RFETCH ; Copy return stack top to data stack - .WORD C_COUNT ; Convert string at addr to addr + length - .WORD C_DUP ; Duplicate top value on stack - .WORD C_1PLUS ; 1 plus - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_PLUS ; Add length of string +1 - .WORD C_MOVER ; Move value from data to return stack - .WORD C_TYPE ; Output n bytes from addr - .WORD C_STOP ; Pop BC from return stack (=next) - -W_QUOTE: ; Accept following text - .BYTE $C2,".",$22+$80 - .WORD W_CQUOTE -C_QUOTE: - .WORD E_COLON ; Interpret following word sequence - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD $0022 - .WORD C_STATE ; Push STATE addr - .WORD C_FETCH ; Get word from addr on stack - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B000A-$ ; 0012h - .WORD C_COMPILE ; Compile next word into dictionary - .WORD C_CQUOTE - .WORD C_WORD - .WORD C_CFETCH ; Get byte from addr on stack - .WORD C_1PLUS ; 1 plus - .WORD C_ALLOT - .WORD C_BRANCH ; Add following offset to BC - .WORD B000B-$ ; 0008h -B000A: - .WORD C_WORD - .WORD C_COUNT ; Convert string at addr to addr + length - .WORD C_TYPE ; Output n bytes from addr -B000B: - .WORD C_STOP ; Pop BC from return stack (=next) - -W_EXPECT: - .BYTE $86,"EXPEC",'T'+$80 - .WORD W_QUOTE -C_EXPECT: - .WORD E_COLON ; Interpret following word sequence - .WORD C_OVER ; Copy buffer start addr - .WORD C_PLUS ; Add to length to give start,end - .WORD C_OVER ; Copy start - .WORD C_LDO ; Put start & end loop values on RPP -B0012: - .WORD C_KEY ; Wait for key, value on stack - .WORD C_DUP ; Duplicate key value - .WORD C_LIT ; Push backspace addr - .WORD BACKSPACE - .WORD C_FETCH ; Get backspace value - .WORD C_EQUALS ; Was it backspace ? - .WORD C_0BRANCH ; If not then jump - .WORD B000C-$ ; 002Ah - .WORD C_DROP ; Drop top value from stack - .WORD C_DUP ; Duplicate top value on stack - .WORD C_I ; Copy LOOP index to data stack - .WORD C_EQUALS - .WORD C_DUP ; Duplicate top value on stack - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_2 - .WORD C_MINUS - .WORD C_PLUS ; n1 + n2 - .WORD C_MOVER ; Move value from data to return stack - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B000D-$ ; 00$0A - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 0007h - .WORD C_BRANCH ; Add following offset to BC - .WORD B000E-$ ; 0006h -B000D: - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 0008h -B000E: - .WORD C_BRANCH ; Add following offset to BC - .WORD B000F-$ ; 0028h -B000C: - .WORD C_DUP ; Duplicate key value - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 00$0D ; CR - .WORD C_EQUALS ; Was it cariage return - .WORD C_0BRANCH ; If not then jump - .WORD B0010-$ ; 000Eh - .WORD C_LEAVE ; Quit loop by making index = limit - .WORD C_DROP ; Drop top value from stack - .WORD C_BL ; Leaves ASCII for space on stack - .WORD C_ZERO ; Put zero on stack - .WORD C_BRANCH ; Add following offset to BC - .WORD B0011-$ ; 0004h -B0010: - .WORD C_DUP ; Duplicate key value -B0011: - .WORD C_I ; Copy LOOP index to data stack - .WORD C_CSTORE ; Store byte at addr - .WORD C_ZERO ; Put zero on stack - .WORD C_I ; Copy LOOP index to data stack - .WORD C_1PLUS ; 1 plus - .WORD C_STORE ; Store word at addr -B000F: - .WORD C_EMIT ; Output CHR from stack - .WORD C_LLOOP ; Increment loop & branch if not done - .WORD B0012-$ ; FF9Eh - .WORD C_DROP ; Drop top value from stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_QUERY: - .BYTE $85,"QUER",'Y'+$80 - .WORD W_EXPECT -C_QUERY: - .WORD E_COLON ; Interpret following word sequence - .WORD C_TIB ; Put TIB addr on stack - .WORD C_FETCH ; Get word from addr on stack - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD $0050 ; Max line length 50h - .WORD C_EXPECT ; Get line - .WORD C_ZERO ; Put zero on stack - .WORD C_TOIN ; Current input buffer offset - .WORD C_STORE ; Store word at addr - .WORD C_STOP ; Pop BC from return stack (=next) - -W_NULL: - .BYTE $C1,$80 - .WORD W_QUERY -C_NULL: - .WORD E_COLON ; Interpret following word sequence - .WORD C_BLK - .WORD C_FETCH ; Get word from addr on stack - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B0013-$ ; 002Ah - .WORD C_1 ; Put 1 on stack - .WORD C_BLK - .WORD C_PLUSSTORE ; Add n1 to addr - .WORD C_ZERO ; Put zero on stack - .WORD C_TOIN ; Current input buffer offset - .WORD C_STORE ; Store word at addr - .WORD C_BLK - .WORD C_FETCH ; Get word from addr on stack - .WORD C_BSCR ; Number of buffers per block on stack - .WORD C_1 ; Put 1 on stack - .WORD C_MINUS - .WORD C_AND ; AND - .WORD C_0EQUALS ; =0 - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B0014-$ ; 0008h - .WORD C_QEXEC ; Error not if not in execute mode - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_DROP ; Drop top value from stack -B0014: - .WORD C_BRANCH ; Add following offset to BC - .WORD B0015-$ ; 0006h -B0013: - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_DROP ; Drop top value from stack -B0015: - .WORD C_STOP ; Pop BC from return stack (=next) - -W_FILL: ; Fill with byte n bytes from addr - .BYTE $84,"FIL",'L'+$80 - .WORD W_NULL -C_FILL: - .WORD 2+$ ; Vector to code - LD L,C ; Save BC for now - LD H,B ; - POP DE ; get byte - POP BC ; get n - EX (SP),HL ; get addr and save BC - EX DE,HL ; -NEXT_BYTE: - LD A,B ; Test count - OR C ; - JR Z,NO_COUNT ; If 0 we're done - LD A,L ; Byte into A - LD (DE),A ; Save byte - INC DE ; Next addr - DEC BC ; Decr count - JR NEXT_BYTE ; Loop -NO_COUNT: - POP BC ; Get BC back - JP NEXT - -W_ERASE: ; Fill addr & length from stack with 0 - .BYTE $85,"ERAS",'E'+$80 - .WORD W_FILL -C_ERASE: - .WORD E_COLON ; Interpret following word sequence - .WORD C_ZERO ; Put zero on stack - .WORD C_FILL ; Fill with byte n bytes from addr - .WORD C_STOP ; Pop BC from return stack (=next) - -W_BLANKS: ; Fill addr & length from stack with [SP] - .BYTE $86,"BLANK",'S'+$80 - .WORD W_ERASE -C_BLANKS: - .WORD E_COLON ; Interpret following word sequence - .WORD C_BL ; Leaves ASCII for space on stack - .WORD C_FILL ; Fill with byte n bytes from addr - .WORD C_STOP ; Pop BC from return stack (=next) - -W_HOLD: - .BYTE $84,"HOL",'D'+$80 - .WORD W_BLANKS -C_HOLD: - .WORD E_COLON ; Interpret following word sequence - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD $FFFF - .WORD C_HLD - .WORD C_PLUSSTORE ; Add n1 to addr - .WORD C_HLD - .WORD C_FETCH ; Get word from addr on stack - .WORD C_CSTORE ; Store byte at addr - .WORD C_STOP ; Pop BC from return stack (=next) - -W_PAD: - .BYTE $83,"PA",'D'+$80 - .WORD W_HOLD -C_PAD: - .WORD E_COLON ; Interpret following word sequence - .WORD C_HERE ; Dictionary pointer onto stack - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 0044h - .WORD C_PLUS ; n1 + n2 - .WORD C_STOP ; Pop BC from return stack (=next) - -W_WORD: - .BYTE $84,"WOR",'D'+$80 - .WORD W_PAD -C_WORD: - .WORD E_COLON ; Interpret following word sequence - .WORD C_BLK - .WORD C_FETCH ; Get word from addr on stack - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B0016-$ ; 000Ch - .WORD C_BLK - .WORD C_FETCH ; Get word from addr on stack - .WORD C_BLOCK - .WORD C_BRANCH ; Add following offset to BC - .WORD B0017-$ ; 0006h -B0016: - .WORD C_TIB - .WORD C_FETCH ; Get word from addr on stack -B0017: - .WORD C_TOIN ; Current input buffer offset - .WORD C_FETCH ; Get word from addr on stack - .WORD C_PLUS ; n1 + n2 - .WORD C_SWAP ; Swap top 2 values on stack - .WORD C_ENCLOSE - .WORD C_HERE ; Dictionary pointer onto stack - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 0022h - .WORD C_BLANKS - .WORD C_TOIN ; Current input buffer offset - .WORD C_PLUSSTORE ; Add n1 to addr - .WORD C_OVER ; Copy 2nd down to top of stack - .WORD C_MINUS - .WORD C_MOVER ; Move value from data to return stack - .WORD C_RFETCH ; Return stack top to data stack - .WORD C_HERE ; Dictionary pointer onto stack - .WORD C_CSTORE ; Store byte at addr - .WORD C_PLUS ; n1 + n2 - .WORD C_HERE ; Dictionary pointer onto stack - .WORD C_1PLUS ; 1 plus - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_CMOVE ; Move block - .WORD C_HERE ; Dictionary pointer onto stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_CONVERT: - .BYTE $87,"CONVER",'T'+$80 - .WORD W_WORD -C_CONVERT: - .WORD E_COLON ; Interpret following word sequence -B001A: - .WORD C_1PLUS ; 1 plus - .WORD C_DUP ; Duplicate top value on stack - .WORD C_MOVER ; Move value from data to return stack - .WORD C_CFETCH ; Get byte from addr on stack - .WORD C_BASE ; Put BASE addr on stack - .WORD C_FETCH ; Get word from addr on stack - .WORD C_DIGIT ; Convert digit n2 using base n1 - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B0018-$ ; 002Ch - .WORD C_SWAP ; Swap top 2 values on stack - .WORD C_BASE ; Put BASE addr on stack - .WORD C_FETCH ; Get word from addr on stack - .WORD C_USTAR - .WORD C_DROP ; Drop top value from stack - .WORD C_ROT ; 3rd value down to top of stack - .WORD C_BASE ; Put BASE addr on stack - .WORD C_FETCH ; Get word from addr on stack - .WORD C_USTAR - .WORD C_DPLUS - .WORD C_DPL - .WORD C_FETCH ; Get word from addr on stack - .WORD C_1PLUS ; 1 plus - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B0019-$ ; 0008h - .WORD C_1 ; Put 1 on stack - .WORD C_DPL - .WORD C_PLUSSTORE ; Add n1 to addr -B0019: - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_BRANCH ; Add following offset to BC - .WORD B001A-$ ; FF$C6 -B0018: - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_NUMBER: - .BYTE $86,"NUMBE",'R'+$80 - .WORD W_CONVERT -C_NUMBER: - .WORD E_COLON ; Interpret following word sequence - .WORD C_ZERO ; Put zero on stack - .WORD C_ZERO ; Put zero on stack - .WORD C_ROT ; 3rd value down to top of stack - .WORD C_DUP ; Duplicate top value on stack - .WORD C_1PLUS ; 1 plus - .WORD C_CFETCH ; Get byte from addr on stack - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 002Dh ; '-' - .WORD C_EQUALS ; Is first chr = '-' - .WORD C_DUP ; Duplicate negative flag - .WORD C_MOVER ; Move value from data to return stack - .WORD C_PLUS ; n1 + n2 - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD $FFFF ;-1 -B001C: - .WORD C_DPL - .WORD C_STORE ; Store word at addr - .WORD C_CONVERT - .WORD C_DUP ; Duplicate top value on stack - .WORD C_CFETCH ; Get byte from addr on stack - .WORD C_BL ; Leaves ASCII for space on stack - .WORD C_MINUS - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B001B-$ ; 0016h - .WORD C_DUP ; Duplicate top value on stack - .WORD C_CFETCH ; Get byte from addr on stack - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 002Eh ; '.' - .WORD C_MINUS - .WORD C_ZERO ; Put zero on stack - .WORD C_QERROR - .WORD C_ZERO ; Put zero on stack - .WORD C_BRANCH ; Add following offset to BC - .WORD B001C-$ ; FFDCh -B001B: - .WORD C_DROP ; Drop top value from stack - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B001D-$ ; 0004h - .WORD C_DNEGATE -B001D: - .WORD C_STOP ; Pop BC from return stack (=next) - -W_MFIND: - .BYTE $85,"-FIN",'D'+$80 - .WORD W_NUMBER -C_MFIND: - .WORD E_COLON ; Interpret following word sequence - .WORD C_BL ; Leaves ASCII for space on stack - .WORD C_WORD - .WORD C_CONTEXT - .WORD C_FETCH ; Get word from addr on stack - .WORD C_FETCH ; Get word from addr on stack - .WORD C_FIND ; Find word & return vector,byte & flag - .WORD C_DUP ; Duplicate top value on stack - .WORD C_0EQUALS ; =0 - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B001E-$ ; 00$0A - .WORD C_DROP ; Drop top value from stack - .WORD C_HERE ; Dictionary pointer onto stack - .WORD C_LATEST ; Push top words NFA - .WORD C_FIND ; Find word & return vector,byte & flag -B001E: - .WORD C_STOP ; Pop BC from return stack (=next) - -W_CABORT: - .BYTE $87,"'+$80 - .WORD W_MFIND -C_CABORT: - .WORD E_COLON ; Interpret following word sequence - .WORD C_ABORT - .WORD C_STOP ; Pop BC from return stack (=next) - -W_ERROR: - .BYTE $85,"ERRO",'R'+$80 - .WORD W_CABORT -C_ERROR: - .WORD E_COLON ; Interpret following word sequence - .WORD C_WARNING ; Put WARNING addr on stack - .WORD C_FETCH ; Get word from addr on stack - .WORD C_0LESS ; Less than 0 leaves true - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B001F-$ ; 0004h - .WORD C_CABORT -B001F: - .WORD C_HERE ; Dictionary pointer onto stack - .WORD C_COUNT ; Convert string at addr to addr + length - .WORD C_TYPE ; Output n bytes from addr - .WORD C_CQUOTE ; Output following string - .BYTE S_END7-S_START7 -S_START7: - .BYTE "? " -S_END7: - .WORD C_MESSAGE ; Output message - .WORD C_SPSTORE ; Set initial stack pointer value - .WORD C_BLK - .WORD C_FETCH ; Get word from addr on stack - .WORD C_QUERYDUP - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B0020-$ ; 0008h - .WORD C_TOIN ; Current input buffer offset - .WORD C_FETCH ; Get word from addr on stack - .WORD C_SWAP ; Swap top 2 values on stack -B0020: - .WORD C_QUIT - -W_ID: ; Print definition name from name field addr - .BYTE $83,"ID",'.'+$80 - .WORD W_ERROR -C_ID: - .WORD E_COLON ; Interpret following word sequence - .WORD C_COUNT ; Convert string at addr to addr + length - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 001Fh ; Max length is 1Fh - .WORD C_AND ; AND lenght with 1Fh - .WORD C_TYPE ; Output n bytes from addr - .WORD C_SPACE ; Output space - .WORD C_STOP ; Pop BC from return stack (=next) - -C_XXX1: - .WORD E_COLON ; Interpret following word sequence - .WORD C_MFIND ; Find name returns PFA,length,true or false - .WORD C_0BRANCH ; Branch if name not found - .WORD B0021-$ ; 0010h - .WORD C_DROP ; Drop length - .WORD C_NFA ; Convert PFA to NFA - .WORD C_ID ; Print definition name from name field addr - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD $0004 ; Message 4, name defined twice - .WORD C_MESSAGE ; Output message - .WORD C_SPACE ; Output space -B0021: - .WORD C_HERE ; Dictionary pointer onto stack - .WORD C_DUP ; Duplicate top value on stack - .WORD C_CFETCH ; Get byte from addr on stack - .WORD C_WIDTH - .WORD C_FETCH ; Get word from addr on stack - .WORD C_MIN - .WORD C_1PLUS ; 1 plus - .WORD C_ALLOT ; Which ever is smallest width or namelength - .WORD C_DUP ; Duplicate top value on stack - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD $00A0 - .WORD C_TOGGLE ; XOR (addr) with byte - .WORD C_HERE ; Dictionary pointer onto stack - .WORD C_1 ; Put 1 on stack - .WORD C_MINUS - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD $0080 - .WORD C_TOGGLE ; XOR (addr) with byte - .WORD C_LATEST ; Push top words NFA - .WORD C_COMMA ; Reserve 2 bytes and save n - .WORD C_CURRENT - .WORD C_FETCH ; Get word from addr on stack - .WORD C_STORE ; Store word at addr - .WORD C_HERE ; Dictionary pointer onto stack - .WORD C_2PLUS ; 2 plus - .WORD C_COMMA ; Reserve 2 bytes and save n - .WORD C_STOP ; Pop BC from return stack (=next) - -W_CCOMPILE: - .BYTE $89,"[COMPILE",']'+$80 - .WORD W_ID -C_CCOMPILE: - .WORD E_COLON ; Interpret following word sequence - .WORD C_MFIND - .WORD C_0EQUALS ; =0 - .WORD C_ZERO ; Put zero on stack - .WORD C_QERROR - .WORD C_DROP ; Drop top value from stack - .WORD C_CFA ; Convert PFA to CFA - .WORD C_COMMA ; Reserve 2 bytes and save n - .WORD C_STOP ; Pop BC from return stack (=next) - -W_LITERAL: - .BYTE $C7,"LITERA",'L'+$80 - .WORD W_CCOMPILE -C_LITERAL: - .WORD E_COLON ; Interpret following word sequence - .WORD C_STATE ; Push STATE addr - .WORD C_FETCH ; Get word from addr on stack - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B0022-$ ; 0008h - .WORD C_COMPILE ; Compile next word into dictionary - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD C_COMMA ; Reserve 2 bytes and save n -B0022: - .WORD C_STOP ; Pop BC from return stack (=next) - -W_DLITERAL: - .BYTE $C8,"DLITERA",'L'+$80 - .WORD W_LITERAL -C_DLITERAL: - .WORD E_COLON ; Interpret following word sequence - .WORD C_STATE ; Push STATE addr - .WORD C_FETCH ; Get word from addr on stack - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B0023-$ ; 0008h - .WORD C_SWAP ; Swap top 2 values on stack - .WORD C_LITERAL - .WORD C_LITERAL -B0023: - .WORD C_STOP ; Pop BC from return stack (=next) - -W_QSTACK: - .BYTE $86,"?STAC",'K'+$80 - .WORD W_DLITERAL -C_QSTACK: - .WORD E_COLON ; Interpret following word sequence - .WORD C_SPFETCH ; Stack pointer onto stack - .WORD C_S0 ; Push S0 (initial data stack pointer) - .WORD C_FETCH ; Get word from addr on stack - .WORD C_SWAP ; Swap top 2 values on stack - .WORD C_ULESS ; IF stack-1 < stack_top leave true flag - .WORD C_1 ; Put 1 on stack - .WORD C_QERROR - .WORD C_SPFETCH ; Stack pointer onto stack - .WORD C_HERE ; Dictionary pointer onto stack - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD $0080 - .WORD C_PLUS ; n1 + n2 - .WORD C_ULESS ; IF stack-1 < stack_top leave true flag - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD $0007 - .WORD C_QERROR - .WORD C_STOP ; Pop BC from return stack (=next) - -W_INTERPRET: - .BYTE $89,"INTERPRE",'T'+$80 - .WORD W_QSTACK -C_INTERPRET: - .WORD E_COLON ; Interpret following word sequence -B002A: - .WORD C_MFIND ; Find name returns PFA,length,true or false - .WORD C_0BRANCH ; Branch if name not found - .WORD NO_NAME-$ - .WORD C_STATE ; STATE addr on stack - .WORD C_FETCH ; Get STATE - .WORD C_LESSTHAN ; Is it quit compile word ? - .WORD C_0BRANCH ; If so then branch - .WORD B0025-$ ; - .WORD C_CFA ; Convert PFA to CFA - .WORD C_COMMA ; Reserve 2 bytes and save n - .WORD C_BRANCH ; Add following offset to BC - .WORD B0026-$ ; -B0025: - .WORD C_CFA ; Convert PFA to CFA - .WORD C_EXECUTE ; Jump to address on stack -B0026: - .WORD C_QSTACK ; Error message if stack underflow - .WORD C_BRANCH ; Add following offset to BC - .WORD B0027-$ ; -NO_NAME: - .WORD C_HERE ; Dictionary pointer onto stack - .WORD C_NUMBER ; Convert string at addr to double - .WORD C_DPL ; - .WORD C_FETCH ; Get word from addr on stack - .WORD C_1PLUS ; 1 plus - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B0028-$ ; - .WORD C_DLITERAL - .WORD C_BRANCH ; Add following offset to BC - .WORD B0029-$ ; -B0028: - .WORD C_DROP ; Drop top value from stack - .WORD C_LITERAL -B0029: - .WORD C_QSTACK ; Error message if stack underflow -B0027: - .WORD C_BRANCH ; Add following offset to BC - .WORD B002A-$ ; FF$C2 - -W_IMMEDIATE: - .BYTE $89,"IMMEDIAT",'E'+$80 - .WORD W_INTERPRET -C_IMMEDIATE: - .WORD E_COLON ; Interpret following word sequence - .WORD C_LATEST ; Push top words NFA - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD $0040 - .WORD C_TOGGLE ; XOR (addr) with byte - .WORD C_STOP ; Pop BC from return stack (=next) - -W_VOCABULARY: - .BYTE 8Ah,"VOCABULAR",'Y'+$80 - .WORD W_IMMEDIATE -C_VOCABULARY: - .WORD E_COLON ; Interpret following word sequence - .WORD C_CREATE - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD $A081 - .WORD C_COMMA ; Reserve 2 bytes and save n - .WORD C_CURRENT - .WORD C_FETCH ; Get word from addr on stack - .WORD C_CFA ; Convert PFA to CFA - .WORD C_COMMA ; Reserve 2 bytes and save n - .WORD C_HERE ; Dictionary pointer onto stack - .WORD C_VOC_LINK - .WORD C_FETCH ; Get word from addr on stack - .WORD C_COMMA ; Reserve 2 bytes and save n - .WORD C_VOC_LINK - .WORD C_STORE ; Store word at addr - .WORD C_DOES - .WORD C_2PLUS ; 2 plus - .WORD C_CONTEXT - .WORD C_STORE ; Store word at addr - .WORD C_STOP ; Pop BC from return stack (=next) - -C_LINK: - .WORD C_2PLUS ; 2 plus - .WORD C_FETCH ; Get word from addr on stack - .WORD C_CONTEXT - .WORD C_STORE ; Store word at addr - .WORD C_STOP ; Pop BC from return stack (=next) - -W_FORTH: - .BYTE $C5,"FORT",'H'+$80 - .WORD W_VOCABULARY -C_FORTH: - .WORD X_DOES - .WORD C_LINK - - .BYTE $81,' '+$80 - .WORD FLAST+2 -E_FORTH: - .WORD $0000 - -W_DEFINITIONS: ; Set CURRENT as CONTEXT vocabulary - .BYTE 8Bh,"DEFINITION",'S'+$80 - .WORD W_FORTH -C_DEFINITIONS: - .WORD E_COLON ; Interpret following word sequence - .WORD C_CONTEXT ; Get CONTEXT addr - .WORD C_FETCH ; Get word from addr on stack - .WORD C_CURRENT ; Get CURRENT addr - .WORD C_STORE ; Set CURRENT as the context vocabulary - .WORD C_STOP ; Pop BC from return stack (=next) - -W_OPENBRKT: - .BYTE $C1,'('+$80 - .WORD W_DEFINITIONS -C_OPENBRKT: - .WORD E_COLON ; Interpret following word sequence - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD $0029 - .WORD C_WORD - .WORD C_DROP ; Drop top value from stack - .WORD C_STOP ; Pop BC from return stack (=next) -;--------------------------------------------------------------------------------------- -; This it the last thing ever executed and is the interpreter -; outer loop. This NEVER quits. -;--------------------------------------------------------------------------------------- -W_QUIT: .BYTE $84,"QUI",'T'+$80 - .WORD W_OPENBRKT -C_QUIT: - .WORD E_COLON ; Interpret following word sequence - .WORD C_ZERO ; Put zero on stack - .WORD C_BLK ; Get current BLK pointer - .WORD C_STORE ; Set BLK to 0 - .WORD C_LEFTBRKT ; Set STATE to execute -B002C: - .WORD C_RPSTORE ; Set initial return stack pointer - .WORD C_CR ; Output [CR][LF] - .WORD C_QUERY ; Get string from input, ends in CR - .WORD C_INTERPRET ; Interpret input stream - .WORD C_STATE ; Push STATE addr - .WORD C_FETCH ; Get word from addr on stack - .WORD C_0EQUALS ; =0 - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD S_END8-$ ; 0007h - .WORD C_CQUOTE ; Output following string - .BYTE S_END8-S_START8 -S_START8: - .BYTE "OK" -S_END8: - .WORD C_BRANCH ; Add following offset to BC - .WORD B002C-$ ; FFE7h - -W_ABORT: - .BYTE $85,"ABOR",'T'+$80 - .WORD W_QUIT -C_ABORT: - .WORD E_COLON ; Interpret following word sequence - .WORD C_UABORT ; Put UABORT on stack - .WORD C_FETCH ; Get word from addr on stack - .WORD C_EXECUTE ; Jump to address on stack - .WORD C_STOP ; Pop BC from return stack (=next) - -CF_UABORT: - .WORD E_COLON ; Interpret following word sequence - .WORD C_SPSTORE ; Set initial stack pointer value - .WORD C_DECIMAL ; Sets decimal mode - .WORD C_QSTACK ; Error message if stack underflow - .WORD C_CR ; Output [CR][LF] - .WORD C_CQUOTE ; Output following string - .BYTE S_END1-S_START1 ; String length -S_START1: - .BYTE "* Z80 FORTH *" -S_END1: - .WORD C_FORTH - .WORD C_DEFINITIONS ; Set CURRENT as CONTEXT vocabulary - .WORD C_QUIT - -W_WARM: - .BYTE $84,"WAR",'M'+$80 - .WORD W_ABORT -C_WARM: - .WORD E_COLON ; Interpret following word sequence - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD WORD1 ; Start of detault table - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD S0 ; S0 addr - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD START_TABLE-WORD1 ; (000Ch) Table length - .WORD C_CMOVE ; Move block - .WORD C_ABORT - -X_COLD: - LD HL,START_TABLE ; Copy table to ram - LD DE,FLAST ; Where the table's going - LD BC,NEXTS2-START_TABLE ; Bytes to copy - LDIR ; - LD HL,W_TASK ; Copy TASK to ram - LD DE,VOCAB_BASE ; Where it's going - LD BC,W_TASKEND-W_TASK ; Bytes to copy - LDIR ; - LD BC,FIRSTWORD ; BC to first forth word - LD HL,(WORD1) ; Get stack pointer - LD SP,HL ; Set it - JP NEXT - -FIRSTWORD: - .WORD C_COLD - -W_COLD: .BYTE $84,"COL",'D'+$80 - .WORD W_WARM - .WORD X_COLD -C_COLD: .WORD E_COLON ; Interpret following word sequence - .WORD C_EBUFFERS ; Clear pseudo disk buffer - .WORD C_ZERO ; Put zero on stack - .WORD C_OFFSET ; Put disk block offset on stack - .WORD C_STORE ; Clear disk block offset - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD WORD1 ; Start of default table - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD S0 ; S0 addr - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD START_TABLE-WORD1 ; Block length on stack (0010h) - .WORD C_CMOVE ; Move block - .WORD C_ABORT - -W_SINGTODUB: ; Change single number to double - .BYTE $84,"S->",'D'+$80 - .WORD W_COLD -C_SINGTODUB: - .WORD 2+$ ; Vector to code - POP DE ; Get number - LD HL,$0000 ; Assume +ve extend - LD A,D ; Check sign - AND $80 ; - JR Z,IS_POS ; Really +ve so jump - DEC HL ; Make -ve extension -IS_POS: - JP NEXTS2 ; Save both & NEXT - -W_PLUSMINUS: - .BYTE $82,"+",'-'+$80 - .WORD W_SINGTODUB -C_PLUSMINUS: - .WORD E_COLON ; Interpret following word sequence - .WORD C_0LESS ; Less than 0 - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B002D-$ ; 0004h - .WORD C_NEGATE ; Form 2s complement of n -B002D: - .WORD C_STOP ; Pop BC from return stack (=next) - -W_DPLUSMINUS: ; Add sign of n to double - .BYTE $83,"D+",'-'+$80 - .WORD W_PLUSMINUS -C_DPLUSMINUS: - .WORD E_COLON ; Interpret following word sequence - .WORD C_0LESS ; Less than 0 - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B002E-$ ; 0004h - .WORD C_DNEGATE -B002E: - .WORD C_STOP ; Pop BC from return stack (=next) - -W_ABS: - .BYTE $83,"AB",'S'+$80 - .WORD W_DPLUSMINUS -C_ABS: - .WORD E_COLON ; Interpret following word sequence - .WORD C_DUP ; Duplicate top value on stack - .WORD C_PLUSMINUS - .WORD C_STOP ; Pop BC from return stack (=next) - -W_DABS: - .BYTE $84,"DAB",'S'+$80 - .WORD W_ABS -C_DABS: - .WORD E_COLON ; Interpret following word sequence - .WORD C_DUP ; Duplicate top value on stack - .WORD C_DPLUSMINUS ; Add sign of n to double - .WORD C_STOP ; Pop BC from return stack (=next) - -W_MIN: - .BYTE $83,"MI",'N'+$80 - .WORD W_DABS -C_MIN: - .WORD E_COLON ; Interpret following word sequence - .WORD C_2DUP ; Dup top 2 values on stack - .WORD C_GREATER - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B002F-$ ; 0004h - .WORD C_SWAP ; Swap top 2 values on stack -B002F: - .WORD C_DROP ; Drop top value from stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_MAX: - .BYTE $83,"MA",'X'+$80 - .WORD W_MIN -C_MAX: - .WORD E_COLON ; Interpret following word sequence - .WORD C_2DUP ; Dup top 2 values on stack - .WORD C_LESSTHAN - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B0030-$ ; 0004h - .WORD C_SWAP ; Swap top 2 values on stack -B0030: - .WORD C_DROP ; Drop top value from stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_MTIMES: - .BYTE $82,"M",'*'+$80 - .WORD W_MAX -C_MTIMES: - .WORD E_COLON ; Interpret following word sequence - .WORD C_2DUP ; Dup top 2 values on stack - .WORD C_XOR ; Works out sign of result - .WORD C_MOVER ; Move value from data to return stack - .WORD C_ABS - .WORD C_SWAP ; Swap top 2 values on stack - .WORD C_ABS - .WORD C_USTAR - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_DPLUSMINUS ; Add sign of n to double - .WORD C_STOP ; Pop BC from return stack (=next) - -W_MDIV: - .BYTE $82,"M",'/'+$80 - .WORD W_MTIMES -C_MDIV: - .WORD E_COLON ; Interpret following word sequence - .WORD C_OVER ; Copy 2nd down to top of stack - .WORD C_MOVER ; Move value from data to return stack - .WORD C_MOVER ; Move value from data to return stack - .WORD C_DABS - .WORD C_RFETCH ; Return stack top to data stack - .WORD C_ABS - .WORD C_UMOD ; Unsigned divide & MOD - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_RFETCH ; Return stack top to data stack - .WORD C_XOR ; XOR - .WORD C_PLUSMINUS - .WORD C_SWAP ; Swap top 2 values on stack - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_PLUSMINUS - .WORD C_SWAP ; Swap top 2 values on stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_TIMES: - .BYTE $81,'*'+$80 - .WORD W_MDIV -C_TIMES: - .WORD E_COLON ; Interpret following word sequence - .WORD C_MTIMES - .WORD C_DROP ; Drop top value from stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_DIVMOD: - .BYTE $84,"/MO",'D'+$80 - .WORD W_TIMES -C_DIVMOD: - .WORD E_COLON ; Interpret following word sequence - .WORD C_MOVER ; Move value from data to return stack - .WORD C_SINGTODUB ; Change single number to double - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_MDIV - .WORD C_STOP ; Pop BC from return stack (=next) - -W_DIV: - .BYTE $81,'/'+$80 - .WORD W_DIVMOD -C_DIV: - .WORD E_COLON ; Interpret following word sequence - .WORD C_DIVMOD - .WORD C_SWAP ; Swap top 2 values on stack - .WORD C_DROP ; Drop top value from stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_MOD: - .BYTE $83,"MO",'D'+$80 - .WORD W_DIV -C_MOD: - .WORD E_COLON ; Interpret following word sequence - .WORD C_DIVMOD - .WORD C_DROP ; Drop top value from stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_TIMESDIVMOD: - .BYTE $85,"*/MO",'D'+$80 - .WORD W_MOD -C_TIMESDIVMOD: - .WORD E_COLON ; Interpret following word sequence - .WORD C_MOVER ; Move value from data to return stack - .WORD C_MTIMES - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_MDIV - .WORD C_STOP ; Pop BC from return stack (=next) - -W_TIMESDIV: - .BYTE $82,"*",'/'+$80 - .WORD W_TIMESDIVMOD -C_TIMESDIV: - .WORD E_COLON ; Interpret following word sequence - .WORD C_TIMESDIVMOD - .WORD C_SWAP ; Swap top 2 values on stack - .WORD C_DROP ; Drop top value from stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_MDIVMOD: - .BYTE $85,"M/MO",'D'+$80 - .WORD W_TIMESDIV -C_MDIVMOD: - .WORD E_COLON ; Interpret following word sequence - .WORD C_MOVER ; Move value from data to return stack - .WORD C_ZERO ; Put zero on stack - .WORD C_RFETCH ; Return stack top to data stack - .WORD C_UMOD ; Unsigned divide & MOD - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_SWAP ; Swap top 2 values on stack - .WORD C_MOVER ; Move value from data to return stack - .WORD C_UMOD ; Unsigned divide & MOD - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_CLINE: - .BYTE $86,"'+$80 - .WORD W_MDIVMOD -C_CLINE: - .WORD E_COLON ; Interpret following word sequence - .WORD C_MOVER ; Move value from data to return stack - .WORD C_CL ; Put characters/line on stack - .WORD C_BBUF ; Put bytes per block on stack - .WORD C_TIMESDIVMOD - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_BSCR ; Number of buffers per block on stack - .WORD C_TIMES - .WORD C_PLUS ; n1 + n2 - .WORD C_BLOCK - .WORD C_PLUS ; n1 + n2 - .WORD C_CL ; Put characters/line on stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_DOTLINE: - .BYTE $85,".LIN",'E'+$80 - .WORD W_CLINE -C_DOTLINE: - .WORD E_COLON ; Interpret following word sequence - .WORD C_CLINE - .WORD C_TRAILING - .WORD C_TYPE ; Output n bytes from addr - .WORD C_STOP ; Pop BC from return stack (=next) - -W_MESSAGE: - .BYTE $87,"MESSAG",'E'+$80 - .WORD W_DOTLINE -C_MESSAGE: - .WORD E_COLON ; Interpret following word sequence - .WORD C_WARNING ; Put WARNING addr on stack - .WORD C_FETCH ; Get WARNING value - .WORD C_0BRANCH ; If WARNING = 0 output MSG # n - .WORD B0031-$ ; 001Eh - .WORD C_QUERYDUP - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B0032-$ ; 0014h - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD $0004 - .WORD C_OFFSET ; Put disk block offset on stack - .WORD C_FETCH ; Get word from addr on stack - .WORD C_BSCR ; Number of buffers per block on stack - .WORD C_DIV - .WORD C_MINUS - .WORD C_DOTLINE ; Output line from screen - .WORD C_SPACE ; Output space - -B0032: .WORD C_BRANCH ; Add following offset to BC - .WORD B0033-$ ; 00$0D - -B0031: .WORD C_CQUOTE ; Output following string - .BYTE S_END2-S_START2 -S_START2: .BYTE "MSG # " -S_END2: .WORD C_DOT -B0033: .WORD C_STOP ; Pop BC from return stack (=next) - -W_PORTIN: ; Fetch data from port - .BYTE $82,"P",'@'+$80 - .WORD W_MESSAGE -C_PORTIN: - .WORD 2+$ ; Vector to code - POP DE ; Get port addr - LD HL,PAT+1 ; Save in port in code - LD (HL),E ; - CALL PAT ; Call port in routine - LD L,A ; Save result - LD H,$00 ; - JP NEXTS1 ; Save & NEXT - -W_PORTOUT: ; Save data to port - .BYTE $82,"P",'!'+$80 - .WORD W_PORTIN -C_PORTOUT: - .WORD 2+$ ; Vector to code - POP DE ; Get port addr - LD HL,PST+1 ; Save in port out code - LD (HL),E ; - POP HL ; - LD A,L ; Byte to A - CALL PST ; Call port out routine - JP NEXT - -W_USE: .BYTE $83,"US",'E'+$80 - .WORD W_PORTOUT -C_USE: .WORD X_USER ; Put next word on stack then do next - .WORD USE-SYSTEM - -W_PREV: .BYTE $84,"PRE",'V'+$80 - .WORD W_USE -C_PREV: .WORD X_USER ; Put next word on stack then do next - .WORD PREV-SYSTEM - -W_PLUSBUF: - .BYTE $84,"+BU",'F'+$80 - .WORD W_PREV -C_PLUSBUF: - .WORD NEXT - -W_UPDATE: - .BYTE $86,"UPDAT",'E'+$80 - .WORD W_PLUSBUF -C_UPDATE: - .WORD NEXT - -W_EBUFFERS: ; Clear pseudo disk buffer - .BYTE $8D,"EMPTY-BUFFER",'S'+$80 - .WORD W_UPDATE -C_EBUFFERS: - .WORD E_COLON ; Interpret following word sequence - .WORD C_FIRST ; Start of pseudo disk onto stack - .WORD C_LIMIT ; End of pseudo disk onto stack - .WORD C_OVER ; Start to top of stack - .WORD C_MINUS ; Work out buffer length - .WORD C_ERASE ; Fill addr & length from stack with 0 - .WORD C_STOP ; Pop BC from return stack (=next) - -W_BUFFER: - .BYTE $86,"BUFFE",'R'+$80 - .WORD W_EBUFFERS -C_BUFFER: - .WORD E_COLON ; Interpret following word sequence - .WORD C_BLOCK - .WORD C_STOP ; Pop BC from return stack (=next) - -W_BLOCK: ; Put address of block n (+ offset) on stack - .BYTE $85,"BLOC",'K'+$80 - .WORD W_BUFFER -C_BLOCK: - .WORD E_COLON ; Interpret following word sequence - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD DISK_END/BLOCK_SIZE-DISK_START/BLOCK_SIZE - ; Max number of blocks - .WORD C_MOD ; MOD to max number - .WORD C_OFFSET ; Put address of disk block offset on stack - .WORD C_FETCH ; Get disk block offset - .WORD C_PLUS ; Add offset to block # - .WORD C_BBUF ; Put bytes per block on stack - .WORD C_TIMES ; Bytes times block number - .WORD C_FIRST ; Put address of first block on stack - .WORD C_PLUS ; Add address of first to byte offset - .WORD C_STOP ; Pop BC from return stack (=next) - -W_RW: - .BYTE $83,"R/",'W'+$80 - .WORD W_BLOCK -C_RW: - .WORD E_COLON ; Interpret following word sequence - .WORD C_URW ; - .WORD C_FETCH ; Get word from addr on stack - .WORD C_EXECUTE ; Jump to address on stack - .WORD C_STOP ; Pop BC from return stack (=next) -CF_URW: - .WORD E_COLON ; Interpret following word sequence - .WORD C_DROP ; Drop top value from stack - .WORD C_DROP ; Drop top value from stack - .WORD C_DROP ; Drop top value from stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_FLUSH: - .BYTE $85,"FLUS",'H'+$80 - .WORD W_RW -C_FLUSH: - .WORD E_COLON ; Interpret following word sequence - .WORD C_STOP ; Pop BC from return stack (=next) - -W_DUMP: - .BYTE $84,"DUM",'P'+$80 - .WORD W_FLUSH -C_DUMP: - .WORD E_COLON ; Interpret following word sequence - .WORD C_ZERO ; Put zero on stack - .WORD C_LDO ; Put start & end loop values on RPP -B0051: - .WORD C_CR ; Output [CR][LF] - .WORD C_DUP ; Duplicate top value on stack - .WORD C_ZERO ; Put zero on stack - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 0005h - .WORD C_DDOTR - .WORD C_SPACE ; Output space - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 0004h - .WORD C_SWAP ; Swap top 2 values on stack - .WORD C_OVER ; Copy 2nd down to top of stack - .WORD C_ZERO ; Put zero on stack - .WORD C_LDO ; Put start & end loop values on RPP -B0050: - .WORD C_DUP ; Duplicate top value on stack - .WORD C_CFETCH ; Get byte from addr on stack - .WORD C_3 - .WORD C_DOTR - .WORD C_1PLUS ; 1 plus - .WORD C_LLOOP ; Increment loop & branch if not done - .WORD B0050-$ ; FFF4h - .WORD C_SWAP ; Swap top 2 values on stack - .WORD C_PLOOP ; Loop + stack & branch if not done - .WORD B0051-$ ; FFD4h - .WORD C_DROP ; Drop top value from stack - .WORD C_CR ; Output [CR][LF] - .WORD C_STOP ; Pop BC from return stack (=next) - -W_LOAD: - .BYTE $84,"LOA",'D'+$80 - .WORD W_DUMP -C_LOAD: - .WORD E_COLON ; Interpret following word sequence - .WORD C_BLK ; Get current block number (0 = keyboard) - .WORD C_FETCH ; Get word from addr on stack - .WORD C_MOVER ; Save it for now - .WORD C_TOIN ; Current input buffer offset - .WORD C_FETCH ; Get word from addr on stack - .WORD C_MOVER ; Save it for now - .WORD C_ZERO ; Put zero on stack - .WORD C_TOIN ; Current input buffer offset - .WORD C_STORE ; Set to zero - .WORD C_BSCR ; Number of buffers per block on stack - .WORD C_TIMES ; Multiply block to load by buffers/block - .WORD C_BLK ; Get BLK pointer - .WORD C_STORE ; Make load block current input stream - .WORD C_INTERPRET ; Interpret input stream - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_TOIN ; Current input buffer offset - .WORD C_STORE ; Store word at addr - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_BLK ; Current block - .WORD C_STORE ; Store word at addr - .WORD C_STOP ; Pop BC from return stack (=next) - -W_NEXTSCREEN: - .BYTE $C3,"--",'>'+$80 - .WORD W_LOAD -C_NEXTSCREEN: - .WORD E_COLON ; Interpret following word sequence - .WORD C_QLOADING - .WORD C_ZERO ; Put zero on stack - .WORD C_TOIN ; Current input buffer offset - .WORD C_STORE ; Store word at addr - .WORD C_BSCR ; Number of buffers per block on stack - .WORD C_BLK - .WORD C_FETCH ; Get word from addr on stack - .WORD C_OVER ; Copy 2nd down to top of stack - .WORD C_MOD - .WORD C_MINUS - .WORD C_BLK - .WORD C_PLUSSTORE ; Add n1 to addr - .WORD C_STOP ; Pop BC from return stack (=next) - -W_TICK: - .BYTE $81,$2C+$80 - .WORD W_NEXTSCREEN -C_TICK: - .WORD E_COLON ; Interpret following word sequence - .WORD C_MFIND ; Find name returns PFA,length,true or false - .WORD C_0EQUALS ; =0 - .WORD C_ZERO ; Put zero on stack - .WORD C_QERROR - .WORD C_DROP ; Drop top value from stack - .WORD C_LITERAL - .WORD C_STOP ; Pop BC from return stack (=next) - -W_FORGET: - .BYTE $86,"FORGE",'T'+$80 - .WORD W_TICK -C_FORGET: - .WORD E_COLON ; Interpret following word sequence - .WORD C_CURRENT - .WORD C_FETCH ; Get word from addr on stack - .WORD C_CONTEXT - .WORD C_FETCH ; Get word from addr on stack - .WORD C_MINUS - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 0018h - .WORD C_QERROR - .WORD C_TICK - .WORD C_DUP ; Duplicate top value on stack - .WORD C_FENCE - .WORD C_FETCH ; Get word from addr on stack - .WORD C_LESSTHAN - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 0015h - .WORD C_QERROR - .WORD C_DUP ; Duplicate top value on stack - .WORD C_NFA ; Convert PFA to NFA - .WORD C_DP ; Dictionary pointer addr on stack - .WORD C_STORE ; Store word at addr - .WORD C_LFA - .WORD C_FETCH ; Get word from addr on stack - .WORD C_CONTEXT - .WORD C_FETCH ; Get word from addr on stack - .WORD C_STORE ; Store word at addr - .WORD C_STOP ; Pop BC from return stack (=next) - -W_BACK: - .BYTE $84,"BAC",'K'+$80 - .WORD W_FORGET -C_BACK: - .WORD E_COLON ; Interpret following word sequence - .WORD C_HERE ; Dictionary pointer onto stack - .WORD C_MINUS - .WORD C_COMMA ; Reserve 2 bytes and save n - .WORD C_STOP ; Pop BC from return stack (=next) - -W_BEGIN: - .BYTE $C5,"BEGI",'N'+$80 - .WORD W_BACK -C_BEGIN: - .WORD E_COLON ; Interpret following word sequence - .WORD C_QCOMP ; Error if not in compile mode - .WORD C_HERE ; Dictionary pointer onto stack - .WORD C_1 ; Put 1 on stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_ENDIF: - .BYTE $C5,"ENDI",'F'+$80 - .WORD W_BEGIN -C_ENDIF: - .WORD E_COLON ; Interpret following word sequence - .WORD C_QCOMP ; Error if not in compile mode - .WORD C_2 - .WORD C_QPAIRS - .WORD C_HERE ; Dictionary pointer onto stack - .WORD C_OVER ; Copy 2nd down to top of stack - .WORD C_MINUS - .WORD C_SWAP ; Swap top 2 values on stack - .WORD C_STORE ; Store word at addr - .WORD C_STOP ; Pop BC from return stack (=next) - -W_THEN: - .BYTE $C4,"THE",'N'+$80 - .WORD W_ENDIF -C_THEN: - .WORD E_COLON ; Interpret following word sequence - .WORD C_ENDIF - .WORD C_STOP ; Pop BC from return stack (=next) - -W_DO: - .BYTE $C2,"D",'O'+$80 - .WORD W_THEN -C_DO: - .WORD E_COLON ; Interpret following word sequence - .WORD C_COMPILE ; Compile next word into dictionary - .WORD C_LDO ; Put start & end loop values on RPP - .WORD C_HERE ; Dictionary pointer onto stack - .WORD C_3 - .WORD C_STOP ; Pop BC from return stack (=next) - -W_LOOP: - .BYTE $C4,"LOO",'P'+$80 - .WORD W_DO -C_LOOP: - .WORD E_COLON ; Interpret following word sequence - .WORD C_3 - .WORD C_QPAIRS - .WORD C_COMPILE ; Compile next word into dictionary - .WORD C_LLOOP ; Increment loop & branch if not done - .WORD C_BACK - .WORD C_STOP ; Pop BC from return stack (=next) - -W_PLUSLOOP: - .BYTE $C5,"+LOO",'P'+$80 - .WORD W_LOOP -C_PLUSLOOP: - .WORD E_COLON ; Interpret following word sequence - .WORD C_3 - .WORD C_QPAIRS - .WORD C_COMPILE ; Compile next word into dictionary - .WORD C_PLOOP ; Loop + stack & branch if not done - .WORD C_BACK - .WORD C_STOP ; Pop BC from return stack (=next) - -W_UNTIL: - .BYTE $C5,"UNTI",'L'+$80 - .WORD W_PLUSLOOP -C_UNTIL: - .WORD E_COLON ; Interpret following word sequence - .WORD C_1 ; Put 1 on stack - .WORD C_QPAIRS - .WORD C_COMPILE ; Compile next word into dictionary - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD C_BACK - .WORD C_STOP ; Pop BC from return stack (=next) - -W_END: - .BYTE $C3,"EN",'D'+$80 - .WORD W_UNTIL -C_END: - .WORD E_COLON ; Interpret following word sequence - .WORD C_UNTIL - .WORD C_STOP ; Pop BC from return stack (=next) - -W_AGAIN: - .BYTE $C5,"AGAI",'N'+$80 - .WORD W_END -C_AGAIN: - .WORD E_COLON ; Interpret following word sequence - .WORD C_1 ; Put 1 on stack - .WORD C_QPAIRS - .WORD C_COMPILE ; Compile next word into dictionary - .WORD C_BRANCH ; Add following offset to BC - .WORD C_BACK - .WORD C_STOP ; Pop BC from return stack (=next) - -W_REPEAT: - .BYTE $C6,"REPEA",'T'+$80 - .WORD W_AGAIN -C_REPEAT: - .WORD E_COLON ; Interpret following word sequence - .WORD C_MOVER ; Move value from data to return stack - .WORD C_MOVER ; Move value from data to return stack - .WORD C_AGAIN - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_2 - .WORD C_MINUS - .WORD C_ENDIF - .WORD C_STOP ; Pop BC from return stack (=next) - -W_IF: - .BYTE $C2,"I",'F'+$80 - .WORD W_REPEAT -C_IF: - .WORD E_COLON ; Interpret following word sequence - .WORD C_COMPILE ; Compile next word into dictionary - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD C_HERE ; Dictionary pointer onto stack - .WORD C_ZERO ; Put zero on stack - .WORD C_COMMA ; Reserve 2 bytes and save n - .WORD C_2 - .WORD C_STOP ; Pop BC from return stack (=next) - -W_ELSE: - .BYTE $C4,"ELS",'E'+$80 - .WORD W_IF -C_ELSE: - .WORD E_COLON ; Interpret following word sequence - .WORD C_2 - .WORD C_QPAIRS - .WORD C_COMPILE ; Compile next word into dictionary - .WORD C_BRANCH ; Add following offset to BC - .WORD C_HERE ; Dictionary pointer onto stack - .WORD C_ZERO ; Put zero on stack - .WORD C_COMMA ; Reserve 2 bytes and save n - .WORD C_SWAP ; Swap top 2 values on stack - .WORD C_2 - .WORD C_ENDIF - .WORD C_2 - .WORD C_STOP ; Pop BC from return stack (=next) - -W_WHILE: .BYTE $C5,"WHIL",'E'+$80 - .WORD W_ELSE -C_WHILE: - .WORD E_COLON ; Interpret following word sequence - .WORD C_IF - .WORD C_2PLUS ; 2 plus - .WORD C_STOP ; Pop BC from return stack (=next) - -W_SPACES: - .BYTE $86,"SPACE",'S'+$80 - .WORD W_WHILE -C_SPACES: - .WORD E_COLON ; Interpret following word sequence - .WORD C_ZERO ; Put zero on stack - .WORD C_MAX - .WORD C_QUERYDUP - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B0034-$ ; 000Ch - .WORD C_ZERO ; Put zero on stack - .WORD C_LDO ; Put start & end loop values on RPP -B0035: .WORD C_SPACE ; Output space - .WORD C_LLOOP ; Increment loop & branch if not done - .WORD B0035-$ ; FFFCh -B0034: .WORD C_STOP ; Pop BC from return stack (=next) - -W_LESSHARP: - .BYTE $82,"<",'#'+$80 - .WORD W_SPACES -C_LESSHARP: - .WORD E_COLON ; Interpret following word sequence - .WORD C_PAD ; Save intermediate string address - .WORD C_HLD - .WORD C_STORE ; Store word at addr - .WORD C_STOP ; Pop BC from return stack (=next) - -W_SHARPGT: - .BYTE $82,"#",'>'+$80 - .WORD W_LESSHARP -C_SHARPGT: - .WORD E_COLON ; Interpret following word sequence - .WORD C_DROP ; Drop top value from stack - .WORD C_DROP ; Drop top value from stack - .WORD C_HLD - .WORD C_FETCH ; Get word from addr on stack - .WORD C_PAD ; Save intermediate string address - .WORD C_OVER ; Copy 2nd down to top of stack - .WORD C_MINUS - .WORD C_STOP ; Pop BC from return stack (=next) - -W_SIGN: - .BYTE $84,"SIG",'N'+$80 - .WORD W_SHARPGT -C_SIGN: - .WORD E_COLON ; Interpret following word sequence - .WORD C_ROT ; 3rd valu down to top of stack - .WORD C_0LESS ; Less than 0 - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B0036-$ ; 0008h - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 002Dh - .WORD C_HOLD -B0036: - .WORD C_STOP ; Pop BC from return stack (=next) - -W_SHARP: - .BYTE $81,'#'+$80 - .WORD W_SIGN -C_SHARP: - .WORD E_COLON ; Interpret following word sequence - .WORD C_BASE ; Put BASE addr on stack - .WORD C_FETCH ; Get word from addr on stack - .WORD C_MDIVMOD - .WORD C_ROT ; 3rd valu down to top of stack - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 0009h - .WORD C_OVER ; Copy 2nd down to top of stack - .WORD C_LESSTHAN - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B0037-$ ; 0008h - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 0007h - .WORD C_PLUS ; n1 + n2 -B0037: - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD $0030 - .WORD C_PLUS ; n1 + n2 - .WORD C_HOLD - .WORD C_STOP ; Pop BC from return stack (=next) - -W_SHARPS: - .BYTE $82,"#",'S'+$80 - .WORD W_SHARP -C_SHARPS: - .WORD E_COLON ; Interpret following word sequence -B0038: - .WORD C_SHARP - .WORD C_OVER ; Copy 2nd down to top of stack - .WORD C_OVER ; Copy 2nd down to top of stack - .WORD C_OR ; OR - .WORD C_0EQUALS ; =0 - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B0038-$ ; FFF4h - .WORD C_STOP ; Pop BC from return stack (=next) - -W_DDOTR: - .BYTE $83,"D.",'R'+$80 - .WORD W_SHARPS -C_DDOTR: - .WORD E_COLON ; Interpret following word sequence - .WORD C_MOVER ; Move value from data to return stack - .WORD C_SWAP ; Swap top 2 values on stack - .WORD C_OVER ; Copy 2nd down to top of stack - .WORD C_DABS - .WORD C_LESSHARP - .WORD C_SHARPS - .WORD C_SIGN - .WORD C_SHARPGT - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_OVER ; Copy 2nd down to top of stack - .WORD C_MINUS - .WORD C_SPACES - .WORD C_TYPE ; Output n bytes from addr - .WORD C_STOP ; Pop BC from return stack (=next) - -W_DOTR: - .BYTE $82,".",'R'+$80 - .WORD W_DDOTR -C_DOTR: - .WORD E_COLON ; Interpret following word sequence - .WORD C_MOVER ; Move value from data to return stack - .WORD C_SINGTODUB ; Change single number to double - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_DDOTR - .WORD C_STOP ; Pop BC from return stack (=next) - -W_DDOT: - .BYTE $82,"D",'.'+$80 - .WORD W_DOTR -C_DDOT: - .WORD E_COLON ; Interpret following word sequence - .WORD C_ZERO ; Put zero on stack - .WORD C_DDOTR - .WORD C_SPACE ; Output space - .WORD C_STOP ; Pop BC from return stack (=next) - -W_DOT: - .BYTE $81,'.'+$80 - .WORD W_DDOT -C_DOT: - .WORD E_COLON ; Interpret following word sequence - .WORD C_SINGTODUB ; Change single number to double - .WORD C_DDOT - .WORD C_STOP ; Pop BC from return stack (=next) - -W_QUESTION: - .BYTE $81,'?'+$80 - .WORD W_DOT -C_QUESTION: - .WORD E_COLON ; Interpret following word sequence - .WORD C_FETCH ; Get word from addr on stack - .WORD C_DOT - .WORD C_STOP ; Pop BC from return stack (=next) - -W_UDOT: ; Output as unsigned value - .BYTE $82,"U",'.'+$80 - .WORD W_QUESTION -C_UDOT: - .WORD E_COLON ; Interpret following word sequence - .WORD C_ZERO ; Put zero on stack - .WORD C_DDOT ; Output double value - .WORD C_STOP ; Pop BC from return stack (=next) - -W_VLIST: - .BYTE $85,"VLIS",'T'+$80 - .WORD W_UDOT -C_VLIST: - .WORD E_COLON ; Interpret following word sequence - .WORD C_CONTEXT ; Leave vocab pointer on stack - .WORD C_FETCH ; Get word from addr on stack - .WORD C_FETCH ; Get word from addr on stack - .WORD C_CR ; Output [CR][LF] -B0039: - .WORD C_DUP ; Duplicate top value on stack - .WORD C_PFA ; Convert NFA to PFA - .WORD C_SWAP ; Swap top 2 values on stack - .WORD C_ID ; Print definition name from name field addr - .WORD C_LFA ; Convert param addr to link addr - .WORD C_FETCH ; Get word from addr on stack - .WORD C_DUP ; Duplicate top value on stack - .WORD C_0EQUALS ; =0 - .WORD C_TERMINAL ; Check for break key - .WORD C_OR ; OR - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B0039-$ ; FFE2h - .WORD C_DROP ; Drop top value from stack - .WORD C_CR ; Output [CR][LF] - .WORD C_STOP ; Pop BC from return stack (=next) - -W_LIST: - .BYTE $84,"LIS",'T'+$80 - .WORD W_VLIST -C_LIST: - .WORD E_COLON ; Interpret following word sequence - .WORD C_BASE ; Put BASE addr on stack - .WORD C_FETCH ; Put current base on stack - .WORD C_SWAP ; Get number of list screen to top - .WORD C_DECIMAL ; Sets decimal mode - .WORD C_CR ; Output [CR][LF] - .WORD C_DUP ; Duplicate top value on stack - .WORD C_SCR ; Set most recently listed - .WORD C_STORE ; Store word at addr - .WORD C_CQUOTE ; Output following string - .BYTE S_END3-S_START3 -S_START3: - .BYTE "SCR # " -S_END3: - .WORD C_DOT ; Output the screen number - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD $0010 ; 16 lines to do - .WORD C_ZERO ; From 0 to 15 - .WORD C_LDO ; Put start & end loop values on RPP -DO_LINE: - .WORD C_CR ; Output [CR][LF] - .WORD C_I ; Line number onto data stack - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD $0003 ; Fromat right justified 3 characters - .WORD C_DOTR ; Output formatted - .WORD C_SPACE ; Output space - .WORD C_I ; Line number onto data stack - .WORD C_SCR ; Get screen number - .WORD C_FETCH ; Get word from addr on stack - .WORD C_DOTLINE ; Output line from screen - .WORD C_TERMINAL ; Check for break key - .WORD C_0BRANCH ; Jump if no break key - .WORD NO_BRK-$ - .WORD C_LEAVE ; Else set loop index to limit (quit loop) -NO_BRK: - .WORD C_LLOOP ; Increment loop & branch if not done - .WORD DO_LINE-$ - .WORD C_CR ; Output [CR][LF] - .WORD C_BASE ; Put BASE addr on stack - .WORD C_STORE ; Restore original base - .WORD C_STOP ; Pop BC from return stack (=next) - -W_INDEX: - .BYTE $85,"INDE",'X'+$80 - .WORD W_LIST -C_INDEX: - .WORD E_COLON ; Interpret following word sequence - .WORD C_1PLUS ; 1 plus - .WORD C_SWAP ; Swap top 2 values on stack - .WORD C_LDO ; Put start & end loop values on RPP -B003D: - .WORD C_CR ; Output [CR][LF] - .WORD C_I ; Copy LOOP index to data stack - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD 0003h - .WORD C_DOTR - .WORD C_SPACE ; Output space - .WORD C_ZERO ; Put zero on stack - .WORD C_I ; Copy LOOP index to data stack - .WORD C_DOTLINE ; Output line from screen - .WORD C_TERMINAL ; Check for break key - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B003C-$ ; 0004h - .WORD C_LEAVE ; Quit loop by making index = limit -B003C: - .WORD C_LLOOP ; Increment loop & branch if not done - .WORD B003D-$ ; FFE4h - .WORD C_CR ; Output [CR][LF] - .WORD C_STOP ; Pop BC from return stack (=next) - -W_INT: - .BYTE $C4,"; IN",'T'+$80 - .WORD W_INDEX -C_INT: - .WORD E_COLON ; Interpret following word sequence - .WORD C_WHATSTACK ; Check stack pointer, error if not ok - .WORD C_COMPILE ; Compile next word into dictionary - .WORD X_INT - .WORD C_LEFTBRKT ; Set STATE to execute - .WORD C_SMUDGE - .WORD C_STOP ; Pop BC from return stack (=next) - -X_INT: - .WORD 2+$ ; Vector to code - LD HL,INTFLAG - RES 6,(HL) - EI - JP X_STOP - -W_INTFLAG: - .BYTE $87,"INTFLA",'G'+$80 - .WORD W_INT -C_INTFLAG: - .WORD X_USER ; Put next word on stack then do next - .WORD INTFLAG-SYSTEM - -W_INTVECT: - .BYTE $87,"INTVEC",'T'+$80 - .WORD W_INTFLAG -C_INTVECT: - .WORD X_USER ; Put next word on stack then do next - .WORD INTVECT-SYSTEM - -W_CPU: - .BYTE $84,".CP",'U'+$80 - .WORD W_INTVECT -C_CPU: - .WORD E_COLON ; Interpret following word sequence - .WORD C_CQUOTE ; Output following string - .BYTE S_END4-S_START4 -S_START4: - .BYTE "Z80 " -S_END4: - .WORD C_STOP ; Pop BC from return stack (=next) - -W_2SWAP: - .BYTE $85,"2SWA",'P'+$80 - .WORD W_CPU -C_2SWAP: - .WORD E_COLON ; Interpret following word sequence - .WORD C_ROT ; 3rd valu down to top of stack - .WORD C_MOVER ; Move value from data to return stack - .WORD C_ROT ; 3rd valu down to top of stack - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_2OVER: - .BYTE $85,"2OVE",'R'+$80 - .WORD W_2SWAP -C_2OVER: - .WORD E_COLON ; Interpret following word sequence - .WORD C_MOVER ; Move value from data to return stack - .WORD C_MOVER ; Move value from data to return stack - .WORD C_2DUP ; Dup top 2 values on stack - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_2SWAP - .WORD C_STOP ; Pop BC from return stack (=next) - -W_EXIT: - .BYTE $84,"EXI",'T'+$80 - .WORD W_2OVER -C_EXIT: - .WORD X_STOP - -W_J: ; Push outer loop value on stack - .BYTE $81,'J'+$80 - .WORD W_EXIT -C_J: - .WORD 2+$ ; Vector to code - LD HL,(RPP) ; Get return stack pointer - INC HL ; Skip inner loop values - INC HL ; - INC HL ; - INC HL ; - JP X_I2 - -W_ROLL: - .BYTE $84,"ROL",'L'+$80 - .WORD W_J -C_ROLL: - .WORD E_COLON ; Interpret following word sequence - .WORD C_DUP ; Duplicate top value on stack - .WORD C_ZERO ; Put zero on stack - .WORD C_GREATER - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B003E-$ ; 002Ch - .WORD C_DUP ; Duplicate top value on stack - .WORD C_MOVER ; Move value from data to return stack - .WORD C_PICK - .WORD C_RMOVE ; Move word from return to data stack - .WORD C_ZERO ; Put zero on stack - .WORD C_SWAP ; Swap top 2 values on stack - .WORD C_LDO ; Put start & end loop values on RPP -B003F: - .WORD C_SPFETCH ; Stack pointer onto stack - .WORD C_I ; Copy LOOP index to data stack - .WORD C_DUP ; Duplicate top value on stack - .WORD C_PLUS ; n1 + n2 - .WORD C_PLUS ; n1 + n2 - .WORD C_DUP ; Duplicate top value on stack - .WORD C_2MINUS ; 2 minus - .WORD C_FETCH ; Get word from addr on stack - .WORD C_SWAP ; Swap top 2 values on stack - .WORD C_STORE ; Store word at addr - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD $FFFF - .WORD C_PLOOP ; Loop + stack & branch if not done - .WORD B003F-$ ; FFE6h -B003E: - .WORD C_DROP ; Drop top value from stack - .WORD C_STOP ; Pop BC from return stack (=next) - -W_DEPTH: - .BYTE $85,"DEPT",'H'+$80 - .WORD W_ROLL -C_DEPTH: - .WORD E_COLON ; Interpret following word sequence - .WORD C_S0 ; Push S0 (initial data stack pointer) - .WORD C_FETCH ; Get word from addr on stack - .WORD C_SPFETCH ; Stack pointer onto stack - .WORD C_MINUS - .WORD C_2 - .WORD C_DIV - .WORD C_1MINUS ; 1 minus - .WORD C_STOP ; Pop BC from return stack (=next) - -W_DLESSTHAN: - .BYTE $82,"D",'<'+$80 - .WORD W_DEPTH -C_DLESSTHAN: - .WORD E_COLON ; Interpret following word sequence - .WORD C_ROT ; 3rd valu down to top of stack - .WORD C_2DUP ; Dup top 2 values on stack - .WORD C_EQUALS - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B0040-$ ; 00$0A - .WORD C_2DROP ; Drop top two values from stack - .WORD C_ULESS ; IF stack-1 < stack_top leave true flag - .WORD C_BRANCH ; Add following offset to BC - .WORD B0041-$ ; 0008h -B0040: - .WORD C_2SWAP - .WORD C_2DROP ; Drop top two values from stack - .WORD C_GREATER -B0041: - .WORD C_STOP ; Pop BC from return stack (=next) - -W_0GREATER: - .BYTE $82,"0",'>'+$80 - .WORD W_DLESSTHAN -C_0GREATER: - .WORD E_COLON ; Interpret following word sequence - .WORD C_ZERO ; Put zero on stack - .WORD C_GREATER - .WORD C_STOP ; Pop BC from return stack (=next) - -W_DOTS: - .BYTE $82,".",'S'+$80 - .WORD W_0GREATER -C_DOTS - .WORD E_COLON ; Interpret following word sequence - .WORD C_CR ; Output [CR][LF] - .WORD C_DEPTH - .WORD C_0BRANCH ; Add offset to BC if stack top = 0 - .WORD B0042-$ ; 0020h - .WORD C_SPFETCH ; Stack pointer onto stack - .WORD C_2MINUS ; 2 minus - .WORD C_S0 ; Push S0 (initial data stack pointer) - .WORD C_FETCH ; Get word from addr on stack - .WORD C_2MINUS ; 2 minus - .WORD C_LDO ; Put start & end loop values on RPP -B0043: - .WORD C_I ; Copy LOOP index to data stack - .WORD C_FETCH ; Get word from addr on stack - .WORD C_DOT - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD $FFFE - .WORD C_PLOOP ; Loop + stack & branch if not done - .WORD B0043-$ ; FFF4h - .WORD C_BRANCH ; Add following offset to BC - .WORD S_END5-$ ; 0011h -B0042: - .WORD C_CQUOTE ; Output following string - .BYTE S_END5-S_START5 -S_START5: - .BYTE "STACK EMPTY " -S_END5: - .WORD C_STOP ; Pop BC from return stack (=next) - -W_CODE: - .BYTE $84,"COD",'E'+$80 - .WORD W_DOTS -C_CODE: - .WORD E_COLON ; Interpret following word sequence - .WORD C_QEXEC ; Error not if not in execute mode - .WORD C_XXX1 - .WORD C_SPSTORE ; Set initial stack pointer value - .WORD C_STOP ; Pop BC from return stack (=next) - -W_ENDCODE: - .BYTE $88,"END-COD",'E'+$80 - .WORD W_CODE -C_ENDCODE: - .WORD E_COLON ; Interpret following word sequence - .WORD C_CURRENT - .WORD C_FETCH ; Get word from addr on stack - .WORD C_CONTEXT - .WORD C_STORE ; Store word at addr - .WORD C_QEXEC ; Error not if not in execute mode - .WORD C_WHATSTACK ; Check stack pointer, error if not ok - .WORD C_SMUDGE - .WORD C_STOP ; Pop BC from return stack (=next) - -W_NEXT: - .BYTE $C4,"NEX",'T'+$80 - .WORD W_ENDCODE -C_NEXT: - .WORD E_COLON ; Interpret following word sequence - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD $00C3 ; Jump instruction - .WORD C_CCOMMA ; Save as 8 bit value - .WORD C_LIT ; Puts next 2 bytes on the stack - .WORD NEXT ; The address of NEXT - .WORD C_COMMA ; Reserve 2 bytes and save n - .WORD C_STOP ; Pop BC from return stack (=next) - -W_IM2: ; Set interrupt mode 2 - .BYTE $83,"IM",'2'+$80 - .WORD W_NEXT -C_IM2: - .WORD 2+$ ; Vector to code - IM 2 ; Mode 2 - JP NEXT - -W_IM1: ; Set interrupt mode 1 - .BYTE $83,"IM",'1'+$80 - .WORD W_IM2 -C_IM1: - .WORD 2+$ ; Vector to code - IM 1 ; Mode 1 - JP NEXT - -W_IM0: ; Set interrupt mode 0 - .BYTE $83,"IM",'0'+$80 - .WORD W_IM1 -C_IM0: - .WORD 2+$ ; Vector to code - IM 0 ; Mode 0 - JP NEXT - -W_DI: ; Disable interrupt - .BYTE $82,"D",'I'+$80 - .WORD W_IM0 -C_DI: - .WORD 2+$ ; Vector to code - DI ; Disable interrupt - JP NEXT - -W_EI: ; Enable interrupt - .BYTE $82,"E",'I'+$80 - .WORD W_DI -C_EI: - .WORD 2+$ ; Vector to code - EI ; Enable interrupt - JP NEXT - -W_MON: ; Jump to m/c monitor - .BYTE $83,"MO",'N'+$80 - .WORD W_EI -C_MON: - .WORD 2+$ - JP MONSTART - -W_LLOAD: - .BYTE $85,"LLOA",'D'+$80 - .WORD W_MON -C_LLOAD: - .WORD E_COLON ; Interpret following word sequence - .WORD C_BLOCK ; Get block address - .WORD C_LIT ; Enter loop with null - .WORD $0000 ; -LL_BEGIN: - .WORD C_DUP ; Dup key - .WORD C_0BRANCH ; If null then don't store - .WORD LL_NULL-$ - .WORD C_DUP ; Dup key again - .WORD C_LIT ; Compare to [CR] - .WORD $000D ; - .WORD C_EQUALS - .WORD C_0BRANCH ; If not [CR] then jump - .WORD LL_STORE-$ ; - .WORD C_DROP ; Drop the [CR] - .WORD C_CL ; Get characters per line - .WORD C_PLUS ; Add to current addr - .WORD C_CL ; Make CL MOD value - .WORD C_NEGATE ; Form 2s complement of n - .WORD C_AND ; Mask out bits - .WORD C_BRANCH ; Done this bit so jump - .WORD NO_STORE-$ -LL_STORE: - .WORD C_OVER ; Get address to store at - .WORD C_STORE ; Save chr -NO_STORE: - .WORD C_1PLUS ; Next addres - .WORD C_BRANCH ; Done so jump - .WORD LL_CHAR-$ -LL_NULL: - .WORD C_DROP ; Was null so drop it -LL_CHAR: - .WORD C_KEY ; Get key - .WORD C_DUP ; Duplicate it - .WORD C_LIT ; Compare with [CTRL] Z - .WORD $001A - .WORD C_EQUALS - .WORD C_0BRANCH ; If not EOF then jump - .WORD LL_BEGIN-$ ; - .WORD C_DROP ; Drop EOF character - .WORD C_DROP ; Drop next address - .WORD C_STOP ; Pop BC from return stack (=next) - -W_TASK: - .BYTE $84,"TAS",'K'+$80 - .WORD W_LLOAD -C_TASK: - .WORD E_COLON ; Interpret following word sequence - .WORD C_STOP ; Pop BC from return stack (=next) -W_TASKEND: - -W_EDITI: - -W_CLEAR: ; Clear block n - .BYTE $85,"CLEA",'R'+$80 - .WORD W_TASK -C_CLEAR: - .WORD E_COLON ; Interpret following word sequence - .WORD C_DUP ; Duplicate number - .WORD C_SCR ; Get SCR addr - .WORD C_STORE ; Store screen number - .WORD C_BLOCK ; Get the address of the block - .WORD C_BBUF ; Put number of bytes/block on stack - .WORD C_ERASE ; Clear the block - .WORD C_STOP ; Pop BC from return stack (=next) - -CF_UKEY: ; Get key onto stack - .WORD 2+$ ; Vector to code - CALL CHR_RD ; User key in routine - LD L,A ; Put key on stack - LD H,$00 ; - JP NEXTS1 ; Save & NEXT - -CF_UEMIT: ; Chr from stack to output - .WORD 2+$ ; Vector to code - POP HL ; Get CHR to output - LD A,L ; Put in A - PUSH BC ; Save regs - PUSH DE ; - CALL CHR_WR ; User output routine - POP DE ; Restore regs - POP BC ; - JP NEXT ; - -CF_UCR: ; CR output - .WORD 2+$ ; Vector to code - PUSH BC ; Save regs - PUSH DE ; Just in case - LD A,$0D ; Carrage return - CALL CHR_WR ; User output routine - LD A,$0A ; Line feed - CALL CHR_WR ; User output routine - POP DE ; Get regs back - POP BC ; - JP NEXT ; Next - -CF_UQTERMINAL: ; Test for user break - .WORD 2+$ ; Vector to code - PUSH BC ; Save regs - PUSH DE ; Just in case - CALL BREAKKEY ; User break test routine - POP DE ; Get regs back - POP BC ; - LD H,$00 ; Clear H - LD L,A ; Result in L - JP NEXTS1 ; Store it & Next - -;------------------------------------------------------------------------------ -; SERIAL I/O ROUTINES -; Change these to suit your target system ..... -;------------------------------------------------------------------------------ -;------------------------------------------------------------------------------ -; RXA - Receive a byte over SIO/0 Ch A -;------------------------------------------------------------------------------ -RXA CALL CKSIOA ; Get the status word - JR NC,RXA ; Loop until a character arrives - IN A,($74) ; Get the character - RET ; Char ready in A -;------------------------------------------------------------------------------ -; TXA - Transmit a byte over SIO/0 Ch A -;------------------------------------------------------------------------------ -TXA PUSH AF ; Store character - CALL CKSIOA ; See if SIO channel A is finished transmitting - JR Z,TXA+1 ; Loop until SIO flag signals ready - POP AF ; Retrieve character - OUT ($74),A ; Output the character - RET -;------------------------------------------------------------------------------ -; Check SIO Channel A status flag, RX char ready=CY, TX buffer clear=NZ -;------------------------------------------------------------------------------ -CKSIOA XOR A ; Zeroize A - OUT ($76),A ; Select Register 0 - IN A,($76) ; Retrieve Status Word - RRCA ; RX status into CY flag - BIT 1,A ; TX Buffer Empty into Z flag - RET -;------------------------------------------------------------------------------ -CHR_RD: CALL RXA ; GET A CHARACTER - CP $61 ; Is UCASE already? - JR C,CHR_RD1 ; It is, leave it alone - CP $7A ; <= "z" ? - JR NC,CHR_RD1 ; - AND $5F ; It's A-Z, or a-z make it upper case -CHR_RD1 RET - -NO_BUF_KEY: - JP RXA ; GET A CHARACTER - -BREAKKEY: CALL CKSIOA ; CHECK USART - JR NC,NO_KEY ; NOTHING - IN A,($74) ; READ THE CHARACTER - CP $03 ; BREAK? - JR Z,WAS_BRK ; YES - CP $61 ; Is UCASE already? - JR C,BRK01 ; It is, leave it alone - CP $7A ; <= "z" ? - JR NC,BRK01 - AND $5F ; It's A-Z, or a-z make it upper case -BRK01 RET ; ELSE RETURN WITH KEY - -NO_KEY: XOR A ; Wasn't break, or no key, so clear - RET - -WAS_BRK: LD A,$01 ; Was break so set flag - RET - -CHR_WR: RST 08H ; WRITE CHARACTER - RET -;------------------------------------------------------------------------------ -FINIS .END -_forth_end:: - .area _CODE - .area _CABS diff --git a/doug/src/hc-old.arf b/doug/src/hc-old.arf deleted file mode 100755 index 3370ec02..00000000 --- a/doug/src/hc-old.arf +++ /dev/null @@ -1,13 +0,0 @@ --mjx --i homecomp.ihx --k /usr/local/share/sdcc/lib/z80 --l z80 --b _CCPB03 = 0x0900 --b _BDOSB01 = 0xD800 --b _CBIOS = 0xE600 --b _DBGMON = 0x0200 -loaderhc.rel -dbgmon.rel -ccpb03.rel -bdosb01.rel -cbios.rel diff --git a/doug/src/jrcb2h.c b/doug/src/jrcb2h.c deleted file mode 100755 index 5b8bebd2..00000000 --- a/doug/src/jrcb2h.c +++ /dev/null @@ -1,528 +0,0 @@ -/* hex2bin.c -- yet another reader and writer of Intel hex files - Copyright (C) 2011 John R Coffman . -*********************************************************************** - When invoked as 'hex2bin' read a sequence of Intel hex files - and create an overlaid binary file. - - When invoked as 'bin2hex' read a binary file and create an - Intel hex file. - - All command line numeric constants may be specified in any - radix. -*********************************************************************** - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - in the file COPYING in the distribution directory along with this - program. If not, see . - -**********************************************************************/ -#include -#include -#include -#include "jrctypes.h" - -#define true 1 -#define false 0 -#define SEG_MASK 0x00FFFFu -#define LBA_MASK 0x00FF0000ul -#define MAX_MASK (LBA_MASK|SEG_MASK) -#define ONE_MEG 0x100000ul - -dword upper_lba = 0; /* upper address */ -dword address_mask = SEG_MASK; /* address mask */ -byte pad = 0xFF; -byte *buffer; -dword rom_size = 0; -dword overwrite; /* count of possible overwrites */ -byte h2b, verbose; -char *outfilename = NULL; -char *binfilename = NULL; -dword source_address, source_limit; -dword dest_address, dest_limit; -FILE *infile; -FILE *outfile; -byte checksum; -char line[1024]; -char *lp; -long int lineno; - - - -dword convert_constant(char *str) -{ - char *final; - dword value = strtoul(str, &final, 0); - - if (*final == 'k' || *final == 'K') value *= 1024ul; - else if (*final == 'M' || *final == 'm') value *= ONE_MEG; - - return value; -} - -void error(byte level, char *msg) -{ - printf("%s(%d): %s\n", - level>1 ? "Error" : "Warning", (int)level, msg); - if (level>1) exit(level); - else if (level==0) printf("line %ld %s", lineno, line); -} - - -int getnibble(void) -{ - char ch; - - if (lp) { - ch = *lp++; - if (ch>='0' && ch<='9') ch -= '0'; - else if (ch>='A' && ch<='F') ch -= 'A'-10; - else if (ch>='a' && ch<='f') ch -= 'a'-10; - else { - error(0,"Illegal hex digit"); - ch = -1; - } - } - else error(0,"Line is too short"); - return (int)ch; -} - -int getbyte(void) -{ - int b = getnibble(); - b <<= 4; - b += getnibble(); - checksum += b; - return b; -} - -int getword(void) -{ - int w = getbyte(); - w <<= 8; - w += getbyte(); - return w; -} - -dword getdword(void) -{ - dword d = getword(); - d <<= 16; - d += getword(); - return d; -} - - -void putbyte(dword address, byte data) -{ - if (address < source_address || address > source_limit) return; - address -= source_address; - address += dest_address; - if (address > dest_limit) return; - if (address >= rom_size) { - printf("Line %ld ",lineno); error(2,"Data beyond end of ROM"); - } - if (buffer[address] != pad) { - overwrite++; - if (verbose || overwrite<=100) printf("Warning(1): Overwrite at ROM address 0x%lX\n", address); - } - buffer[address] = data; -} - - -void usage(void) -{ - printf("hex2bin.c (bin2hex) -- " __DATE__ " " __TIME__ ".\n" - "Copyright (c) 2011 John R Coffman. All rights reserved.\n" - "Distributed under the GNU General Public License, a copy of which\n" - "is contained in the file COPYING in the distribution directory.\n\n"); - if (h2b) printf( - "Usage:\n" - " hex2bin [ ]+\n\n" - " Options:\n" - " -o \n" - " -p \n" - " -R default 64K\n" - " -v []\n" - " Flags:\n" - " -d \n" - " -D \n" - " -s \n" - " -S \n" - ); - else printf( - "Usage:\n" - " bin2hex [ ]+\n\n" - " Options:\n" - " -o \n" - " -p \n" - " -R default 1024K\n" - " -v []\n" - " Flags:\n" - " -d \n" - " -D \n" - " -s \n" - " -S \n" - ); -} - - -void hout_byte(byte data) -{ - checksum -= data; - fprintf(outfile, "%02X", (int)data); -} -void hout_word(word data) -{ - hout_byte(data>>8); - hout_byte(data); -} -void begin_record(byte length) -{ - checksum = 0; - fputc(':', outfile); - hout_byte(length); -} -void end_record(void) -{ - hout_byte(checksum); - fputc('\n', outfile); -} - -void write_lba(dword address) -{ - if (verbose==5) printf("Address: %06lX\n", address); - - if ((address & LBA_MASK) != upper_lba) { - upper_lba = address & LBA_MASK; - begin_record(2); - hout_word(0); - if (rom_size > ONE_MEG) { - hout_byte(4); /* linear address */ - hout_word(upper_lba>>16); - } - else { /* handle ROMs 1meg and smaller */ - hout_byte(2); /* segment address */ - hout_word(upper_lba>>4); - } - end_record(); - } -} - -void write_data(word nbytes, byte *buf, dword address) -{ - /* compress from the high end */ - while (nbytes && buf[nbytes-1]==pad) --nbytes; - /* compress from the low end */ - while (nbytes && *buf==pad) { - ++buf; - ++address; - --nbytes; - } - if (nbytes) { - write_lba(address); - begin_record(nbytes); - hout_word(address & 0xFFFFu); - hout_byte(0); /* data record */ - while(nbytes--) hout_byte(*buf++); - end_record(); - } -} - -#define min(a,b) ((a)<(b)?(a):(b)) -#define NREC 16 - -void write_hex_file(FILE *outfile) -{ - dword nbytes; - dword vaddr; - dword n; - byte *buf; - - buf = buffer; - vaddr = 0; - nbytes = rom_size; - n = min(nbytes, NREC); - do { - write_data(n, buf, vaddr); - buf += n; - vaddr += n; - nbytes -= n; - n = min(nbytes, NREC); - } while (n); -/* write the end-of-file record */ - fprintf(outfile,":00000001FF\n"); -} - - -void scan_bin_file(char *filename) -{ - dword length; - dword nbytes; - int data; - dword inaddr; - - infile = fopen(filename, "rb"); - if (!infile) { - strcpy(line,"Cannot find file: "); - error(5, strcat(line, filename)); - } - - fseek(infile,0L,SEEK_END); - length = ftell(infile); - -// length = filelength(fileno(infile)); - - nbytes = 0; - inaddr = dest_address; - if (source_address < length) { - fseek(infile, source_address, SEEK_SET); - while (inaddr=3) printf("%s", lp-1); - checksum = 0; - ldata = getbyte(); - laddr = getword(); - rectype = getbyte(); - switch (rectype) { - case 0: /* data record */ - index = 0; - while (ldata--) { - data = getbyte(); - putbyte(upper_lba + ((laddr + index)&address_mask), data); - index++; - } - break; - case 1: /* end of file record */ - EndOfFile = 1; - break; - case 2: /* segment address */ - address_mask = SEG_MASK; - value = getword(); - upper_lba = value<<4; /* start of segment */ - ldata -= 2; - break; - case 4: /* linear upper address */ - address_mask = MAX_MASK; - value = getword(); - upper_lba = value<<16; /* full 32-bit address range */ - ldata -= 2; - break; - case 3: /* start CS:IP */ - case 5: /* linear start address */ - value = getdword(); - ldata -= 4; - default: - error(0,"Unknown record type:"); - } - getbyte(); /* get final checksum */ - if (checksum) { - error(0,"Checksum failure"); - } - } while (lp && !EndOfFile); - fclose(infile); -} - - -void global_options(int argc, char *argv[]) -{ - int iarg; - char *cp; - char *tp; - char ch; - - h2b = false; - rom_size = ONE_MEG; /* bin2hex default value */ -/* decide which conversion to do */ - if (strstr(argv[0],"hex2bin") -#ifdef MSDOS - || strstr(argv[0],"HEX2BIN") -#endif - ) { - h2b = true; - rom_size = 64 * 1024ul; /* default value */ - } /* assume 'bin2hex' otherwise */ - - if (argc<2) { usage(); exit(0); } - -/* scan the global command line options */ - for (iarg = 0; iarg MAX_MASK+1) error(5, "ROM size too big"); - if (rom_size < 256) error(5, "ROM size too small"); - *cp = *tp = 0; - break; - case 'v': /* print verbose statistics */ - verbose++; - if (!*tp) tp = argv[++iarg]; - if (*tp>='1' && *tp<='5' && tp[1]==0) verbose += (*tp - '1'); - else tp = cp; - *cp = *tp = 0; - break; - case 'Y': { - int i; - for (i=0; i. -*********************************************************************** - When invoked as 'hex2bin' read a sequence of Intel hex files - and create an overlaid binary file. - - When invoked as 'bin2hex' read a binary file and create an - Intel hex file. - - All command line numeric constants may be specified in any - radix. -*********************************************************************** - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - in the file COPYING in the distribution directory along with this - program. If not, see . - -**********************************************************************/ -#include -#include -#include -#include "jrctypes.h" - -#define true 1 -#define false 0 -#define SEG_MASK 0x00FFFFu -#define LBA_MASK 0x00FF0000ul -#define MAX_MASK (LBA_MASK|SEG_MASK) -#define ONE_MEG 0x100000ul - -dword upper_lba = 0; /* upper address */ -dword address_mask = SEG_MASK; /* address mask */ -byte pad = 0xFF; -byte *buffer; -dword rom_size = 0; -dword overwrite; /* count of possible overwrites */ -byte h2b, verbose; -char *outfilename = NULL; -char *binfilename = NULL; -dword source_address, source_limit; -dword dest_address, dest_limit; -FILE *infile; -FILE *outfile; -byte checksum; -char line[1024]; -char *lp; -long int lineno; - - - -dword convert_constant(char *str) -{ - char *final; - dword value = strtoul(str, &final, 0); - - if (*final == 'k' || *final == 'K') value *= 1024ul; - else if (*final == 'M' || *final == 'm') value *= ONE_MEG; - - return value; -} - -void error(byte level, char *msg) -{ - printf("%s(%d): %s\n", - level>1 ? "Error" : "Warning", (int)level, msg); - if (level>1) exit(level); - else if (level==0) printf("line %ld %s", lineno, line); -} - - -int getnibble(void) -{ - char ch; - - if (lp) { - ch = *lp++; - if (ch>='0' && ch<='9') ch -= '0'; - else if (ch>='A' && ch<='F') ch -= 'A'-10; - else if (ch>='a' && ch<='f') ch -= 'a'-10; - else { - error(0,"Illegal hex digit"); - ch = -1; - } - } - else error(0,"Line is too short"); - return (int)ch; -} - -int getbyte(void) -{ - int b = getnibble(); - b <<= 4; - b += getnibble(); - checksum += b; - return b; -} - -int getword(void) -{ - int w = getbyte(); - w <<= 8; - w += getbyte(); - return w; -} - -dword getdword(void) -{ - dword d = getword(); - d <<= 16; - d += getword(); - return d; -} - - -void putbyte(dword address, byte data) -{ - if (address < source_address || address > source_limit) return; - address -= source_address; - address += dest_address; - if (address > dest_limit) return; - if (address >= rom_size) { - printf("Line %ld ",lineno); error(2,"Data beyond end of ROM"); - } - if (buffer[address] != pad) { - overwrite++; - if (verbose || overwrite<=100) printf("Warning(1): Overwrite at ROM address 0x%lX\n", address); - } - buffer[address] = data; -} - - -void usage(void) -{ - printf("hex2bin.c (bin2hex) -- " __DATE__ " " __TIME__ ".\n" - "Copyright (c) 2011 John R Coffman. All rights reserved.\n" - "Distributed under the GNU General Public License, a copy of which\n" - "is contained in the file COPYING in the distribution directory.\n\n"); - if (h2b) printf( - "Usage:\n" - " hex2bin [ ]+\n\n" - " Options:\n" - " -o \n" - " -p \n" - " -R default 64K\n" - " -v []\n" - " Flags:\n" - " -d \n" - " -D \n" - " -s \n" - " -S \n" - ); - else printf( - "Usage:\n" - " bin2hex [ ]+\n\n" - " Options:\n" - " -o \n" - " -p \n" - " -R default 1024K\n" - " -v []\n" - " Flags:\n" - " -d \n" - " -D \n" - " -s \n" - " -S \n" - ); -} - - -void hout_byte(byte data) -{ - checksum -= data; - fprintf(outfile, "%02X", (int)data); -} -void hout_word(word data) -{ - hout_byte(data>>8); - hout_byte(data); -} -void begin_record(byte length) -{ - checksum = 0; - fputc(':', outfile); - hout_byte(length); -} -void end_record(void) -{ - hout_byte(checksum); - fputc('\n', outfile); -} - -void write_lba(dword address) -{ - if (verbose==5) printf("Address: %06lX\n", address); - - if ((address & LBA_MASK) != upper_lba) { - upper_lba = address & LBA_MASK; - begin_record(2); - hout_word(0); - if (rom_size > ONE_MEG) { - hout_byte(4); /* linear address */ - hout_word(upper_lba>>16); - } - else { /* handle ROMs 1meg and smaller */ - hout_byte(2); /* segment address */ - hout_word(upper_lba>>4); - } - end_record(); - } -} - -void write_data(word nbytes, byte *buf, dword address) -{ - /* compress from the high end */ - while (nbytes && buf[nbytes-1]==pad) --nbytes; - /* compress from the low end */ - while (nbytes && *buf==pad) { - ++buf; - ++address; - --nbytes; - } - if (nbytes) { - write_lba(address); - begin_record(nbytes); - hout_word(address & 0xFFFFu); - hout_byte(0); /* data record */ - while(nbytes--) hout_byte(*buf++); - end_record(); - } -} - -#define min(a,b) ((a)<(b)?(a):(b)) -#define NREC 16 - -void write_hex_file(FILE *outfile) -{ - dword nbytes; - dword vaddr; - dword n; - byte *buf; - - buf = buffer; - vaddr = 0; - nbytes = rom_size; - n = min(nbytes, NREC); - do { - write_data(n, buf, vaddr); - buf += n; - vaddr += n; - nbytes -= n; - n = min(nbytes, NREC); - } while (n); -/* write the end-of-file record */ - fprintf(outfile,":00000001FF\n"); -} - - -void scan_bin_file(char *filename) -{ - dword length; - dword nbytes; - int data; - dword inaddr; - - infile = fopen(filename, "rb"); - if (!infile) { - strcpy(line,"Cannot find file: "); - error(5, strcat(line, filename)); - } - - fseek(infile,0L,SEEK_END); - length = ftell(infile); - -// length = filelength(fileno(infile)); - - nbytes = 0; - inaddr = dest_address; - if (source_address < length) { - fseek(infile, source_address, SEEK_SET); - while (inaddr=3) printf("%s", lp-1); - checksum = 0; - ldata = getbyte(); - laddr = getword(); - rectype = getbyte(); - switch (rectype) { - case 0: /* data record */ - index = 0; - while (ldata--) { - data = getbyte(); - putbyte(upper_lba + ((laddr + index)&address_mask), data); - index++; - } - break; - case 1: /* end of file record */ - EndOfFile = 1; - break; - case 2: /* segment address */ - address_mask = SEG_MASK; - value = getword(); - upper_lba = value<<4; /* start of segment */ - ldata -= 2; - break; - case 4: /* linear upper address */ - address_mask = MAX_MASK; - value = getword(); - upper_lba = value<<16; /* full 32-bit address range */ - ldata -= 2; - break; - case 3: /* start CS:IP */ - case 5: /* linear start address */ - value = getdword(); - ldata -= 4; - default: - error(0,"Unknown record type:"); - } - getbyte(); /* get final checksum */ - if (checksum) { - error(0,"Checksum failure"); - } - } while (lp && !EndOfFile); - fclose(infile); -} - - -void global_options(int argc, char *argv[]) -{ - int iarg; - char *cp; - char *tp; - char ch; - - h2b = false; - rom_size = ONE_MEG; /* bin2hex default value */ -/* decide which conversion to do */ - if (strstr(argv[0],"hex2bin") -#ifdef MSDOS - || strstr(argv[0],"HEX2BIN") -#endif - ) { - h2b = true; - rom_size = 64 * 1024ul; /* default value */ - } /* assume 'bin2hex' otherwise */ - - if (argc<2) { usage(); exit(0); } - -/* scan the global command line options */ - for (iarg = 0; iarg MAX_MASK+1) error(5, "ROM size too big"); - if (rom_size < 256) error(5, "ROM size too small"); - *cp = *tp = 0; - break; - case 'v': /* print verbose statistics */ - verbose++; - if (!*tp) tp = argv[++iarg]; - if (*tp>='1' && *tp<='5' && tp[1]==0) verbose += (*tp - '1'); - else tp = cp; - *cp = *tp = 0; - break; - case 'Y': { - int i; - for (i=0; i -#include -#include - -int main(int argc,char **argv) -{ - char szTemp[128]; - int index; - - strcpy(szTemp,argv[1]); - for(index=0;index -#include -#include - -int main(int argc,char **argv) -{ - char szTemp[128]; - int index; - - strcpy(szTemp,argv[1]); - for(index=0;index -#include -#include - -int main(int argc,char **argv) -{ - char szTemp[128]; - int index; - - strcpy(szTemp,argv[1]); - for(index=0;index -#include -#include - -int main(int argc,char **argv) -{ - char szTemp[128]; - int index; - - strcpy(szTemp,argv[1]); - for(index=0;index2) { - printf(" "); - strcpy(szTemp,argv[2]); - for(index=0;index3) { - printf(" "); - strcpy(szTemp,argv[3]); - for(index=0;index4) { - printf(" "); - strcpy(szTemp,argv[4]); - for(index=0;index -#include -#include - -int main(int argc,char **argv) -{ - char szTemp[128]; - int index; - - strcpy(szTemp,argv[1]); - for(index=0;index. -// - -#include -#include -#include - -#define DATA_RECORD 0x00 -#define EOF_RECORD 0x01 - -int main(int argc,char **argv) -{ - FILE * fcom, * fhex; - char g_szBuffer2[128]; - char szByteBuffer[2+1]; - char *p; - int iTemp; - - char cColon; - - char szLength[2+1]; - int iLength; - - char szAddress[4+1]; - unsigned int uiAddress; - - char szRecordType[2+1]; - unsigned char ucRecordType; - - char szData[80]; - unsigned char ucBinBuffer[32+1]; - - char szChecksum[2+1]; - unsigned char ucChecksum; - - unsigned int uiLastByte = 0; - - char szComFile[255]; - char szHexFile[255]; - int i; - - unsigned char memory[0xfff0]; - - if(1 == argc) { - printf("usage - load \n"); - exit(EXIT_FAILURE); - } - - strcpy(szHexFile,argv[1]); - strcpy(szComFile,argv[1]); - - strcat(szComFile,".com"); - strcat(szHexFile,".hex"); - - memset(memory,0,sizeof(memory)); - - fhex = fopen(szHexFile,"r"); - if(NULL == fhex) { - printf("Sorry, cannot open %s for input\n",szHexFile); - exit(EXIT_FAILURE); - } - p = fgets(g_szBuffer2,sizeof(g_szBuffer2),fhex); - while(NULL != p) { - g_szBuffer2[strlen(g_szBuffer2)-1] = 0; - cColon = g_szBuffer2[0]; - - memset(szLength,0,sizeof(szLength)); - memcpy(szLength,&g_szBuffer2[1],2); - sscanf(szLength,"%02X",&iLength); - - memset(szAddress,0,sizeof(szAddress)); - memcpy(szAddress,&g_szBuffer2[3],4); - sscanf(szAddress,"%04X",&uiAddress); - - memset(szRecordType,0,sizeof(szRecordType)); - memcpy(szRecordType,&g_szBuffer2[7],2); - - sscanf(szRecordType,"%02X",&iTemp); - ucRecordType = (unsigned char)iTemp; - - if(0 == ucRecordType) { - memset(szData,0,sizeof(szData)); - memcpy(szData,&g_szBuffer2[9],iLength*2); - for(i=0;i -#include -#include -#include "portab.h" -#include "scsi2ide.h" -#include "ns16550.h" - - -/* THESE ARE USED BY THE LIBRARY ROUTINES */ -char get_char(void) -{ - while(UART_RDA & rUART_LSR) ; - return rUART_RDR; -} -void out_char(char c) -{ - while(UART_TBE & rUART_LSR) ; - wUART_TDR = c; -} - - -void xdisable(void) -{ -} - -void xenable(void) -{ -} - -void intmode(U8 xmode) -{ - if(xmode); -} - -int main(void) -{ - /* uart init must be done before library - uses input or output primitives */ - wUART_LCR = UART_DLAB; - wUART_DIV_HI = 0; - wUART_DIV_LO = 12; /* 9600 baud */ - wUART_LCR = 0x03; /* 8N1 */ - wUART_MCR = 0x03; - - - printf("\nN8VEM SCSI2IDE-0111 %s Dated %s %s\n", - __FILE__,__DATE__,__TIME__); - - printf("\nmain() completed\n"); - - return (0); -} - diff --git a/doug/src/sdcc.man b/doug/src/sdcc.man deleted file mode 100644 index bc405a00..00000000 --- a/doug/src/sdcc.man +++ /dev/null @@ -1,170 +0,0 @@ -SDCC : mcs51/gbz80/z80/ds390/TININative/ds400/hc08 3.0.2 #6489 (May 10 2011) (Mac OS X x86_64) -Usage : sdcc [options] filename -Options :- - -General options: - --help Display this help - -v --version Display sdcc's version - --verbose Trace calls to the preprocessor, assembler, and linker - -V Execute verbosely. Show sub commands as they are run - -d - -D Define macro as in -Dmacro - -I Add to the include (*.h) path, as in -Ipath - -A - -U - -M Preprocessor option - -W Pass through options to the pre-processor (p), assembler (a) or linker (l) - -S Compile only; do not assemble or link - -c --compile-only Compile and assemble, but do not link - -E --preprocessonly Preprocess only, do not compile - --c1mode Act in c1 mode. The standard input is preprocessed code, the output is assembly code. - -o Place the output into the given path resp. file - --print-search-dirs display the directories in the compiler's search path - --vc messages are compatible with Micro$oft visual studio - --use-stdout send errors to stdout instead of stderr - --nostdlib Do not include the standard library directory in the search path - --nostdinc Do not include the standard include directory in the search path - --less-pedantic Disable some of the more pedantic warnings - --disable-warning Disable specific warning - --Werror Treat the warnings as errors - --debug Enable debugging symbol output - --cyclomatic Display complexity of compiled functions - --std-c89 Use C89 standard only - --std-sdcc89 Use C89 standard with SDCC extensions (default) - --std-c99 Use C99 standard only (incomplete) - --std-sdcc99 Use C99 standard with SDCC extensions (incomplete) - --fdollars-in-identifiers Permit '$' as an identifier character - --funsigned-char Make "char" unsigned by default - --use-non-free Search / include non-free licensed libraries and header files - -Code generation options: - -m Set the port to use e.g. -mz80. - -p Select port specific processor e.g. -mpic14 -p16f84 - --model-small internal data space is used (default) - --model-medium external paged data space is used - --model-large external data space is used - --model-huge functions are banked, data in external space - --stack-auto Stack automatic variables - --xstack Use external stack - --int-long-reent Use reentrant calls on the int and long support functions - --float-reent Use reentrant calls on the float support functions - --main-return Issue a return after main() - --xram-movc Use movc instead of movx to read xram (xdata) - --callee-saves Cause the called function to save registers instead of the caller - --profile On supported ports, generate extra profiling information - --fomit-frame-pointer Leave out the frame pointer. - --all-callee-saves callee will always save registers used - --stack-probe insert call to function __stack_probe at each function prologue - --no-xinit-opt don't memcpy initialized xram from code - --no-c-code-in-asm don't include c-code as comments in the asm file - --no-peep-comments don't include peephole optimizer comments - --fverbose-asm include code generator comments - --short-is-8bits Make short 8 bits (for old times sake) - --codeseg use this name for the code segment - --constseg use this name for the const segment - -Optimization options: - --nooverlay Disable overlaying leaf function auto variables - --nogcse Disable the GCSE optimisation - --nolabelopt Disable label optimisation - --noinvariant Disable optimisation of invariants - --noinduction Disable loop variable induction - --nojtbound Don't generate boundary check for jump tables - --noloopreverse Disable the loop reverse optimisation - --no-peep Disable the peephole assembly file optimisation - --no-reg-params On some ports, disable passing some parameters in registers - --peep-asm Enable peephole optimization on inline assembly - --peep-return Enable peephole optimization for return instructions - --no-peep-return Disable peephole optimization for return instructions - --peep-file use this extra peephole file - --opt-code-speed Optimize for code speed rather than size - --opt-code-size Optimize for code size rather than speed - -Internal debugging options: - --dumpraw Dump the internal structure after the initial parse - --dumpgcse - --dumploop - --dumpdeadcode - --dumpliverange - --dumpregpack - --dumpregassign - --dumptree dump front-end AST before generating iCode - --dumpall Dump the internal structure at all stages - --i-code-in-asm include i-code as comments in the asm file - -Linker options: - -l Include the given library in the link - -L Add the next field to the library search path - --lib-path use this path to search for libraries - --out-fmt-ihx Output in Intel hex format - --out-fmt-s19 Output in S19 hex format - --xram-loc External Ram start location - --xram-size External Ram size - --iram-size Internal Ram size - --xstack-loc External Stack start location - --code-loc Code Segment Location - --code-size Code Segment size - --stack-loc Stack pointer initial value - --data-loc Direct data start location - --idata-loc - -Special options for the mcs51 port: - --stack-size Tells the linker to allocate this space for stack - --parms-in-bank1 use Bank1 for parameter passing - --pack-iram Tells the linker to pack variables in internal ram (default) - --no-pack-iram Deprecated: Tells the linker not to pack variables in internal ram - --acall-ajmp Use acall/ajmp instead of lcall/ljmp - -Special options for the gbz80 port: - -bo use code bank - -ba use data bank - --callee-saves-bc Force a called function to always save BC - --codeseg use this name for the code segment - --constseg use this name for the const segment - --no-std-crt0 For the z80/gbz80 do not link default crt0.rel - -Special options for the z80 port: - --callee-saves-bc Force a called function to always save BC - --portmode= Determine PORT I/O mode (z80/z180) - --asm= Define assembler name (rgbds/asxxxx/isas/z80asm) - --codeseg use this name for the code segment - --constseg use this name for the const segment - --no-std-crt0 For the z80/gbz80 do not link default crt0.rel - --reserve-regs-iy Do not use IY - -Special options for the ds390 port: - --model-flat24 use the flat24 model for the ds390 (default) - --stack-8bit use the 8bit stack for the ds390 (not supported yet) - --stack-size Tells the linker to allocate this space for stack - --pack-iram Tells the linker to pack variables in internal ram (default) - --no-pack-iram Deprecated: Tells the linker not to pack variables in internal ram - --stack-10bit use the 10bit stack for ds390 (default) - --use-accelerator generate code for ds390 arithmetic accelerator - --protect-sp-update will disable interrupts during ESP:SP updates - --parms-in-bank1 use Bank1 for parameter passing - -Special options for the TININative port: - --model-flat24 use the flat24 model for the ds390 (default) - --stack-8bit use the 8bit stack for the ds390 (not supported yet) - --stack-size Tells the linker to allocate this space for stack - --pack-iram Tells the linker to pack variables in internal ram (default) - --no-pack-iram Deprecated: Tells the linker not to pack variables in internal ram - --stack-10bit use the 10bit stack for ds390 (default) - --use-accelerator generate code for ds390 arithmetic accelerator - --protect-sp-update will disable interrupts during ESP:SP updates - --parms-in-bank1 use Bank1 for parameter passing - --tini-libid LibraryID used in -mTININative - -Special options for the ds400 port: - --model-flat24 use the flat24 model for the ds400 (default) - --stack-8bit use the 8bit stack for the ds400 (not supported yet) - --stack-size Tells the linker to allocate this space for stack - --pack-iram Tells the linker to pack variables in internal ram (default) - --no-pack-iram Deprecated: Tells the linker not to pack variables in internal ram - --stack-10bit use the 10bit stack for ds400 (default) - --use-accelerator generate code for ds400 arithmetic accelerator - --protect-sp-update will disable interrupts during ESP:SP updates - --parms-in-bank1 use Bank1 for parameter passing - -Special options for the hc08 port: - --out-fmt-elf Output executable in ELF format diff --git a/doug/src/sysgen.c b/doug/src/sysgen.c deleted file mode 100755 index fa641987..00000000 --- a/doug/src/sysgen.c +++ /dev/null @@ -1,159 +0,0 @@ -/*********************************************************************** - - sysgen utility - - Copyright (C) 2009, Max Scane - - This program allows you to build and manage the N8VEM's system ROM. - - There are three possible functions which are selected by command line parameters: - - sysgen -C xxx image.file : This command allows you to create a blank file of xxx KB in size - - sysgen -e extract.file image.file : This command extracts the 10 KB system "track" to a file - - sysgen -i insert.file image.file : This command inserts (writes) the contents of a file to the system "track" - - -*************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include - - -void usage(void) -{ - printf("N8VEM sysgen v1.0\n"); - printf("usage:\n"); - printf("sysgen -C xx filename - Create filename xx KB in size\n"); - printf("sysgen -i importfile imagefile - Import the contents of importfile to Imagefile\n"); - printf("sysgen -e exportfile imagefile - Export system track to exportfile\n"); - exit(1); -} - -int main(int argc, char *argv[]) - -{ - - int i, size, fd1, fd2, nwritten, nread; - int ntotal = 0; - char buffer [10240]; - - if (argc != 4) - { - printf("\nIncorrect number of parameters\n\n"); - usage(); - } - - - if (strcmp(argv[1], "-C") == 0) /* Create command */ - { - for (i=0; i<1024; i++) buffer[i] = 229; - - fd1 = creat(argv[3],O_WRONLY|S_IRWXU); - - if ( fd1 == -1) - { - printf("error creating file %s\n",argv[3]); - exit(1); - } - for (i=0; i< (atoi(argv[2])) ; i++) - { - nwritten = write (fd1, &buffer, 1024); - if (nwritten == -1) - { - printf ("error writing file %s\n",argv[3]); - exit(1); - } - ntotal+=nwritten; - } - printf("wrote %d bytes to file %s\n",ntotal,argv[3]); - close(fd1); - exit(0); - } - - if (strcmp(argv[1], "-i") == 0) /* Import command */ - { - - fd1 = open (argv[2],O_RDONLY); - if (fd1 == -1) - { - printf("error opening input file %s\n",argv[2]); - exit(1); - } - fd2 = open (argv[3], O_WRONLY); - if ( fd2 == -1) - { - printf("error opening output file %s\n",argv[3]); - exit(1); - } - - nread = read( fd1, &buffer, 10240); - - if (nread == -1) - { - printf ("error reading from input file %s\n", argv[2]); - exit(1); - } - nwritten = write ( fd2, &buffer, nread); - if (nwritten == -1) - { - printf ("error writing to output file %s\n", argv[3]); - exit(1); - } - printf("wrote %d bytes to file %s\n",nwritten,argv[3]); - - close(fd1); - close(fd2); - - exit(0); - } - - if (strcmp(argv[1], "-e") == 0) /* Export command */ - { - - fd1 = creat(argv[2],O_WRONLY|S_IRWXU); /* export file */ - - if (fd1 == -1) - { - printf("error creating export file %s\n",argv[2]); - exit(1); - } - - fd2 = open(argv[3],O_RDONLY); /* romimage file */ - if (fd2 == -1) - { - printf("error opening romimage file %s\n",argv[3]); - exit(1); - } - nread = read( fd2, &buffer, 10240); - if (nread == -1) - { - printf ("error reading from romimage file %s\n",argv[3]); - exit(1); - } - nwritten = write( fd1, &buffer, nread); - if (nwritten == -1) - { - printf ("error writing to outputfile %s\n",argv[2]); - exit(1); - } - printf("wrote %d bytes to file %s\n",nwritten,argv[2]); - - close(fd1); - close(fd2); - - exit(0); - } - - usage(); - - return EXIT_SUCCESS; -} - - diff --git a/doug/src/tester.c b/doug/src/tester.c deleted file mode 100755 index 8038f31c..00000000 --- a/doug/src/tester.c +++ /dev/null @@ -1,7 +0,0 @@ -#include -#include - -int main() -{ - printf( __TIMESTAMP__ ); -} diff --git a/doug/src/verify.c b/doug/src/verify.c deleted file mode 100755 index 05b575c2..00000000 --- a/doug/src/verify.c +++ /dev/null @@ -1,74 +0,0 @@ -#include -#include -#include - -int compare(char *file1,unsigned int offset1,char *file2,unsigned int offset2,unsigned int length) -{ - int count1,count2,index; - unsigned char buffer1[65535]; - unsigned char buffer2[65535]; - FILE * fp1,*fp2; - - fp1 = fopen(file1,"r"); - if(NULL == fp1) { - printf("Sorry, cannot open %s\n",file1); - exit(EXIT_FAILURE); - } - count1 = fread(buffer1,offset1+length,1,fp1); - if(1 != count1) { - printf("Sorry, cannot read %d bytes from %s\n",offset1+length,file1); - printf("bytes read were %d\n",count1); - printf("ferror returned %d\n",ferror(fp1)); - fclose(fp1); - exit(EXIT_FAILURE); - } - fclose(fp1); - - fp2 = fopen(file2,"r"); - if(NULL == fp2) { - printf("Sorry, cannot open %s\n",file2); - fclose(fp1); - exit(EXIT_FAILURE); - } - - count2 = fread(buffer2,length,1,fp2); - if(1 != count2) { - printf("Sorry, cannot read %d bytes from %s\n",length,file2); - fclose(fp2); - exit(EXIT_FAILURE); - } - fclose(fp2); - - for(index=0;index