        TITLE   MDOS Simulator Package
        NAME    MDOSSIM2.0a
EDITDATE        EQU     $1085   **** CHANGE THE FOLLOWING WHEN EDITING *****
VERSION         EQU     2       Different Version --> Major difference in function
Revision        EQU     0       Different Revision --> Minor difference in function
Assembly        equ     'b      Different Assembly --> Bug fixes, etc.
*
*       MDOS Simulator Package
*       This program simulates the MDOS (Trademark: Motorola) operating system,
*       so that MDOS programs can be run (with the aid of this package),
*       under the SDOS operating system.
*       This program occupies the space normally occupied by MDOS ($100-$1FFF),
*       and requires that SWI instructions be vectored to it, so that it
*       can simulate MDOS system calls.
*
*       Revision History:
*
*       7/17/80  Charles McGuinness: m6800 version
*
*       10/17/82 Ira D. Baxter
*           Converted for operation under 6809 SDOS.
*
*       12/22/83 Ronald C. Whites
*           Added fixes and debugged 6800/09
*
*       9/11/84  R.C.W
*           Finished debug of 6809
*
*       9/26/85
*           debug for 6800, required by NAVY for simulating
*           V2.0 SDBASIC/ASM-MDOS on exorcisor
*           set flag swidebug if want swi to be enabled in MDOSSIM
*           added facility to trace MDOS calls for debugging
*
*       V2.0a 10/29/85 IDB
*           Annotated portions of text to make their operation clearer
*           Moved SWI intercept logic to front to make it easier to locate
*           Revised SWI intercept logic to make cleaner
*           Fixed "GETLS doesn't sense EOF properly"
*
*       V2.0b 11/7/85 IDB
*           Fixed .PFNAM logic to correctly skip leading blanks on filenames
*           Fixed STARTUP logic to place command line in $AE correctly
*                 (instead of incorrectly placing it at $80)
*
*       Possible improvements:
*           Include EXBUGSIM?
*           Replace Magic constants by appropriate MDOS definitions
*
        include    sdos11defs.asm
        IF      M6809

SWIVECT EQU     $F3FB   SWI VECT LOCATION

        FIN
        IF      M6800

SWIVECT EQU     $FFFA   SWI VECT LOCATION

        FIN


SWIDEBUG   EQU 1

*       EXORCISOR,CONRAC,PSITECH and OMNIBYTE USE $FFFA
*       MSI Uses $F004
*       SSB Uses $F3FB

        IFUND   M6800
M6800   EQU     0
        FIN
        IFUND   M6809
M6809   EQU     1
        FIN
        IFUND   M6801
M6801   EQU     0
        FIN


MYCHAN  EQU     1
LPTCHAN EQU     1
        page
*
*       REGISTER DISPLACEMENTS INTO CONTEXT BLOCK AFTER SWI INSTRUCTION
*
        IF      M6800!M6801
SWI:REGC        EQU     0
SWI:REGB        EQU     1
SWI:REGA        EQU     2
SWI:REGX        EQU     3
SWI:PC          EQU     5
        ELSE    (M6809)
SWI:REGC        EQU     0
SWI:REGA        EQU     1
SWI:REGB        EQU     2
SWI:REGZ        EQU     3
SWI:REGX        EQU     4
SWI:REGY        EQU     6
SWI:REGU        EQU     8
SWI:PC          EQU     10
        FIN
        page        MDOS equates
*       WHAT FOLLOWS IS LIFTED FROM THE "MDOS" MANUAL
*       **** SYSTEM EQUATE FILE **** FOR MDOS

*
*       MDOS VERSION 2.01 -- SYSTEM EQUATE FILE -- APRIL 29,1977
*
*       DEFINE MULTI-SECTOR/SINGLE SECTOR I/O
*
MULTS   EQU     0       0 => SINGLE SECTOR, 1=> MULTIPLE SECTOR

*       SKIP2, SKIP1, SCALL, UCALL, SEQ MACROS INTENTIONALLY LEFT OUT
*
SCALL   EQU     $3F             SYSTEM CALL
*
*       S Y S T E M   F U N C T I O N   D E F I N I T I O N S
*
*
*       SET LOCATION COUNTER TO 0 FOR THE EQUATE DEFINITIONS
*
:SAV    SET     *               SAVE OLD LOCATION COUNT
        ORG     $0
*
*
*
.RESRV  RMB     1               .RESERVE A DEVICE
.RELES  RMB     1               .RELEASE A DEVICE
.OPEN   RMB     1               .OPEN A FILE
.CLOSE  RMB     1               .CLOSE A FILE
.GETRC  RMB     1               .READ A RECORD
.PUTRC  RMB     1               .WRITE A RECORD
.REWND  RMB     1               .POSITION TO BEGINNING OF FILE
.GETLS  RMB     1               .READ LOGICAL SECTOR
.PUTLS  RMB     1               .WRITE LOGICAL SECTOR
.KEYIN  RMB     1               .CONSOLE INPUT
.DSPLY  RMB     1               .CONSOLE OUTPUT (TERM W/ CR)
.DSPLX  RMB     1               .CONSOLE OUTPUT (TERM W/ EOT)
.DSPLZ  RMB     1               .CONSOLE OUTPUT (TERM W/ EOT, NO CR/LF AT END)
.CKBRK  RMB     1               .CHECK CONSOLE FOR BREAK KEY
.DREAD  RMB     1               .EROM DISK READ
.DWRIT  RMB     1               .EROM DISK WRITE
.MOVE   RMB     1               .MOVE A STRING
.CMPAR  RMB     1               .COMPARE STRINGS
.STCHB  RMB     1               .STORE BLANKS
.STCHR  RMB     1               .STORE CHARACTERS
.ALPHA  RMB     1               .CHECK ALPHABETIC CHARACTER
.NUMD   RMB     1               .CHECK DECIMAL DIGIT
.ADDAM  RMB     1               .INCREMENT MEMORY (DOUBLE BYTE) BY A
.SUBAM  RMB     1               .DECREMENT MEMORY (DOUBLE BYTE) BY A
.MMA    RMB     1               .MULTIPLY (SHIFT LEFT) MEMORY BY A (COUNT)
.DMA    RMB     1               .DIVIDE (SHIFT RIGHT) MEMORY BY A (COUNT)
.MDENT  RMB     1               .ENTER MDOS WITHOUT RELOADING
.LOAD   RMB     1               .LOAD A FILE FROM DISK
.DIRSM  RMB     1               .DIRECTORY SEARCH AND MODIFY
.PFNAM  RMB     1               .PROCESS FILE NAME
.ALUSM  RMB     1               .ALLOCATE USER MEMORY
.CHANG  RMB     1               .CHANGE NAME/ATTRIBUTES
.MDERR  RMB     1               .MDOS ERROR MESSAGE HANDLER
.ALLOC  RMB     1               .ALLOCATE DISK SPACE
.DEALC  RMB     1               .RETURN DISK SPACE
.EWORD  RMB     1               .SET ERROR STATUS WORD FOR CHAIN
.TXBA   RMB     1               .TRANSFER X TO B,A
.TBAX   RMB     1               .TRANSFER B,A TO X
.XBAX   RMB     1               .EXCHANGE B,A AND X
.ADBX   RMB     1               .ADD B TO X
.ADAX   RMB     1               .ADD A TO X
.ADBAX  RMB     1               .ADD B,A TO X
.ADXBA  RMB     1               .ADD X TO B,A
.SUBX   RMB     1               .SUBTRACT B FROM X
.SUAX   RMB     1               .SUBTRACT A FROM X
.SUBAX  RMB     1               .SUBTRACT B,A FROM X
.SUXBA  RMB     1               .SUBTRACT X FROM B,A
.CPBAX  RMB     1               .COMPARE B,A TO X
.ASRX   RMB     1               .SHIFT X RIGHT (ARITHMETIC)
.ASLX   RMB     1               .SHIFT X LEFT (ARITHMETIC/LOGICAL)
.PSHX   RMB     1               .PUSH X ON STACK
.PULX   RMB     1               .PULL X FROM STACK
.PRINT  RMB     1               .PRINT-TERMINATE WITH CR
.PRINX  RMB     1               .PRINT-TERMINATE WITH EOT
.GETFD  RMB     1               .READ FDR
.PUTFD  RMB     1               .WRITE FDR
.PUTEF  RMB     1               .WRITE EOF
.EREAD  RMB     1               .DISK READ W/ ERR RETN
.EWRIT  RMB     1               .DISK WRITE W/ ERR RETN
        RMB     1               *** NOT USED
        RMB     1               *** NOT USED
        RMB     1               *** NOT USED
        RMB     1               *** NOT USED
.BOOT   RMB     1               .RELOAD MDOS
        ORG     :SAV            RESTORE LOCATION COUNTER
*
*
*       A S C I I   C O N T R O L   C H A R A C T E R S
*
NULL    EQU     0               NULL
SOH     EQU     1               START OF HEADING
STX     EQU     2               START OF TEXT
ETX     EQU     3               END OF TEXT
EOT     EQU     4               END OF TEXT
ENQ     EQU     5               ENQUIRY (WRU- WHO ARE YOU)
ACK     EQU     6               ACKNOWLEDGE
BEL     EQU     7               BELL
BS      EQU     8               BACKSPACE
HT      EQU     9               HORIZONTAL TAB
LF      EQU     $A              LINE FEED
VT      EQU     $B              VERTICAL TAB
FF      EQU     $C              FORM FEED
CR      EQU     $D              CARRIAGE RETURN
SO      EQU     $E              SHIFT OUT
SI      EQU     $F              SHIFT IN
DLE     EQU     $10             DATA LINK ESCAPE
DC1     EQU     $11             DEVICE CONROL 1
DC2     EQU     $12             DEVICE CONTROL 2
DC3     EQU     $13             DEVICE CONROL 3
DC4     EQU     $14             DEVICE CONTROL 4
NAK     EQU     $15             NEGATIVE ACKNOWLEDGE
SYN     EQU     $16             SYNCHRONOUS IDLE
ETB     EQU     $17             END OF TRANSMISSION BLOCK
CAN     EQU     $18             CANCEL
EM      EQU     $19             END OF MEDIUM
SUB     EQU     $1A             SUBSTITUTE
ESC     EQU     $1B             ESCAPE
FS      EQU     $1C             FISLE SEPERATOR
GS      EQU     $1D             GROUP SEPERATOR
RS      EQU     $1E             RECORD SEPERATOR
US      EQU     $1F             UNIT SEPERATOR
SPACE   EQU     $20             SPACE (WORD SEPERATOR)
RUBOUT  EQU     $7F             DELETE (RUBOUT)
*
*       S P E C I A L   C H A R A C T E R    E Q U A T E S
*
SUFDLM  EQU     '.              SUFFIX DELIMITER
OPTDLM  EQU     ';              OPTIONS DELIMITER
DRVDLM  EQU     ':              LOGICAL DRIVER DELIMITER
DEVDLM  EQU     '#              GENERIC DEVICE NAME DELIMITER
FAMDLM  EQU     '*              FAMILY NAME/SUFFIX DELIMITER
E$FATL  EQU     1##7            FATAL ERROR BIT
        PAGE
*
*       M D O S   S E C T O R    E Q U A T E S
*
SC$DID  EQU     0               DISK ID PHYSICAL SECTOR NUMBER
SC$CAT  EQU     1               CLUSTER ALLOCATION TABLE PHYSICAL SECTOR NUMBER
SC$LOK  EQU     2               LOCKOUT CLUSTER TABLE PHYSICAL SECTOR NUMBER
SC$DIR  EQU     3               DIRECTORY START PHYSICAL SECTOR NUMBER
SC$DRE  EQU     $16             DIRECTORY END PHYSICAL SECTOR NUMBER
SC$BB   EQU     $17             BOOT BLOCK PHYSICAL SECTOR NUMBER
SC$DOS  EQU     $18             OPERATING SYSTEM PHYSICAL SECTOR NUMBER (RIB ADDRESS)
SC$SIZ  EQU     128             SECTOR SIZE IN BYTES
SC$TRK  EQU     $26             NUMBER OF SECTORS / TRACK
SC$CLS  EQU     4               NUMBER OF SECTORS / CLUSTER
SC$MAX  EQU     2000            MAXIMUM NUMBER OF USABLE SECTORS
DFCLS$  EQU     32              DEFAULT NUMBER OF CLUSTERS
*
*       D I S K    I D    S E C T O R    O F F S E T S
*
DID$ID  EQU     0               OFFSET TO DISK ID (8 BYTES)
DID$VN  EQU     8               OFFSET TO VERSION NUMBER (2 BYTES)
DID$RN  EQU     10              OFFSET TO REVISION NUMBER (2 BYTES)
DID$DT  EQU     12              OFFSET TO DATE (6 BYTES)
DID$NM  EQU     18              OFFSET TO USER NAME (20 BYTES)
DID$RB  EQU     38              OFFSET TO RIB ADDRESS (20 BYTES)
*
*       D I R E C T O R Y    E N T R Y    O F F S E T S
*
DIR$NM  EQU     0               OFFSET TO NAME (8 BYTES)
DIR$SX  EQU     8               OFFSET TO SUFFIX (2 BYTES)
DIR$RB  EQU     10              OFFSET TO RIB ADDRESS
DIR$AT  EQU     12              OFFSET TO ATTRIBUTES (2 BYTES)
DIR$NU  EQU     14              OFFSET TO NOT USED AREA (2 BYTES)
*
*
*       R I B    B I N A R Y    F I L E    O F F S E T S
*
RIB$LB  EQU     117             NUMBER OF BYTES IN LAST SECTOR
RIB$SL  EQU     118             NUMBER OF SECTORS TO LOAD
RIB$LA  EQU     120             MEMORY LOAD ADDRESS
RIB$SA  EQU     122             START EXECUTION ADDRESS
        PAGE
*       U N I F I E D    I / O    C O N T R O L    B L O C K
*
*               O F F S E T S
*
IOCSTA  EQU     0               ERROR STATUS
IOCDTT  EQU     1               DATA TRANSFER TYPE
IOCDBP  EQU     2               DATA BUFFER POINTER
IOCDBS  EQU     4               DATA BUFFER START ADDRESS
IOCDBE  EQU     6               DATA BUFFER END ADDRESS
IOCGDW  EQU     8               GENERIC DEVICE TYPE/CONTROL DESCRIPTOR ADDRESS
IOCLUN  EQU     10              LOGICAL UNIT NUMBER
IOCNAM  EQU     11              FILE NAME
IOCMLS  EQU     11              MAXIMUM REFERENCED LOGICAL SECTOR NUMBER
IOCSDW  EQU     13              CURRENT SEGMENT DESCRIPTOR WORD
IOCSLS  EQU     15              1ST LOGICAL SECTOR OF CURRENT SEGMENT
IOCLSN  EQU     17              CURRENT LOGICAL SECTOR NUMBER
IOCSUF  EQU     19              FILE NAME SUFFIX
IOCEOF  EQU     19              LOGICAL END OF FILE
IOCRIB  EQU     21              PHYSICAL DISK ADDRESS OF RIB
IOCFDF  EQU     23              FILE DESCRIPTOR FLAGS
IOCDEN  EQU     27              DIRECTORY ENTRY NUMBER
IOCSBP  EQU     29              SECTOR BUFFER POINTER/INITIAL ALLOCATION
IOCSBS  EQU     31              SECTOR BUFFER START ADDRESS
IOCSBE  EQU     33              SECTOR BUFFER END ADDRESS
IOCSBI  EQU     35              SECTOR BUFFER INTERNAL PTR
IOCBLN  EQU     IOCSBI+2-IOCSTA IOCB LENGTH
*
*       U N I F I E D    I / O    E R R O R    S T A T U S E S
*
:SAV    SET     *               REMEMBER THE CURRENT LOCATION COUNTER
        ORG     $0              RESET IT TO ZEROT TO USE THE SEQ MACKR
*
I$NOER  RMB     1               NO ERRORS, NORMAL RETURN
I$NODV  RMB     1               NO SUCH DEVICE
I$RESV  RMB     1               DEVICE RESERVED ALREADY
I$NORV  RMB     1               DEVICE NOT RESERVED
I$NRDY  RMB     1               DEVICE NOT READY
I$IVDV  RMB     1               INVALID DEVICE
I$DUPE  RMB     1               DUPLICATE FILE NAME
I$NONM  RMB     1               FILE NAME NOT FOUND
I$CLOS  RMB     1               FILE NAME NOT OPEN/ OR FILE NOT CLOSED
I$EOF   RMB     1               END OF FILE
I$FTYPE RMB     1               INVALID FILE TYPE
I$DTYP  RMB     1               INVALID DATA TRANSFER TYPE
I$EOM   RMB     1               END OF MEDIA
I$BUFO  RMB     1               BUFFER OVERFLOW
I$CKSM  RMB     1               CHECKSUM ERROR
I$WRIT  RMB     1               FILE IS WRITE PROTECTED
I$DELT  RMB     1               FILE IS DELETE PROTECTED
I$RANG  RMB     1               LOGICAL SECTOR NUMBER OUT OF RANGE
I$FSPC  RMB     1               NO DISK FILE SPACE AVAILABLE
I$DSPC  RMB     1               NO DIRECTORY SPACE AVAILABLE
I$SSPC  RMB     1               NO SEGMENT DESCRIPTOR SPACE AVAILABLE
I$IDEN  RMB     1               INVALID DIR. ENTRY NO.
I$RIB   RMB     1               INVALID RIB
I$DEAL  RMB     1               CAN'T DEALLOCATE ALL SPACE
I$RECL  RMB     1               BINARY RECORD LENGTH TOO LARGE

        ORG     :SAV            RESTORE THE LOCATION COUNTER
        PAGE
*       M D O S    I N T E R N A L    V A R I A B L E S
*
*               A N D    L O C A T I O N    E Q U A T E S
*
MDOS$   EQU     $100            START OF MDOS ASECT
CBUFL$  EQU     80              COMMAND BUFFER LENGTH
CBUFF$  EQU     MDOS$-CBUFL$-2  COMMAND BUFFER LOCATION
CBUFP$  EQU     CBUFF$+CBUFL$   COMMAND BUFFER SCAN POINTER
VERS$$  EQU     MDOS$           VERSION #
REVS$$  EQU     VERS$$+2        REVISION #
KYI$SV  EQU     REVS$$+2        SAVE AREA FOR KEYIN$ VECTOR
ENDOS$  EQU     KYI$SV+2        END OF MDOS
ENDUS$  EQU     ENDOS$+2        END OF USER PROGRAM AREA
ENDSY$  EQU     ENDUS$+2        END OF SYSTEM (MDOS) RAM
RIBBA$  EQU     ENDSY$+4        RIB BUFFER ADDRESS
ENDRV$  EQU     RIBBA$+2        END OF MDOS ROM VARIABLES
GDBA$   EQU     ENDRV$+2        GENERIC DEVICE TABLE ADDRESS
SYERR$  EQU     GDBA$+2         SYSTEM ERROR STATUS WORD
SWI$SV  EQU     SYERR$+2        SWI VECTOR SAVE AREA
SWI$UV  EQU     SWI$SV+2        SWI USER VECTOR
IRQ$UV  EQU     SWI$UV+2        IRQ USER VECTOR
IRQ$SV  EQU     IRQ$UV+2        IRQ VECTOR SAVE AREA
CHFLG$  EQU     IRQ$SV+2        CHAIN FUNCTION FLAG WORD
SYIOCB  EQU     CHFLG$+2        CHAIN FUNCTION FLAG WORD
SYPOCB  EQU     SYIOCB+IOCBLN   SYSTEM PRINTER IOCB
SYEOCB  EQU     SYPOCB+IOCBLN   ERR MSG FILE
        PAGE
*
*       L O G I C A L    U N I T    N U M B E R  --   B I T    D E F I N I T I O N S
*
LU$RES  EQU     %01000000       IOCB RESERVED FLAG
*
*       I O C D T T  --  B I T   D E F I N I T I O N S
*
DT$OPP  EQU     %00000000       OPEN UPDATE/INPUT
DT$OPI  EQU     %00000001       OPEN INPUT MODE
DT$OPO  EQU     %00000010       OPEN OUTPUT MODE
DT$OPU  EQU     %00000011       OPEN UPDATE MODE
DT$NFF  EQU     %00000100       NON-FILE FORMAT I/O FLAG
DT$TRU  EQU     %00001000       TRUNCATE FLAG
DT$CLS  EQU     %00010000       FILE OPEN/CLOSE FLAG
DT$SIO  EQU     %00100000       SECTOR I/O FLAG
DT$OUT  EQU     %01000000       OUTPUT TRANSFER TYPE
DT$INP  EQU     %10000000       INPUT TRANSFER TYPE
*
*       I O C F D F  --  B I T    D E F I N I T I O N S
*
FD$FMU  EQU     %00000000       USER DEFINED FORMAT (SECTOR I/O ONLY)
FD$FMD  EQU     %00000001       DEFAULT OBJECT REC'D FORMAT (DEVICE DEPENDENT)
FD$FML  EQU     %00000010       BINARY LOAD FORMAT -- ABSOLUTE MEMORY IMAGE
FD$FMB  EQU     %00000011       BINARY RECORD FORMAT -- RASM OUTPUT, RLOAD INPUT
FD$FMR  EQU     %00000100       BINARY LOAD FORMAT -- RELOCATABLE MEMORY IMAGE
FD$FMA  EQU     %00000101       ASCII RECORD FORMAT -- INCLUDES EXORCISOR LOAD FORMAT
FD$FMC  EQU     %00000111       ASCII-CONVERTED-BINARY RECORD FORMAT
FD$CMP  EQU     %00001000       SPACE COMPRESSION FLAG
FD$CON  EQU     %00010000       CONTIGUOUS ALLOCATION FLAG
FD$SYS  EQU     %00100000       SYSTEM FILE ATTRIBUTE
FD$DEL  EQU     %01000000       DELETE PROTECTION ATTRIBUTE
FD$WRT  EQU     %10000000       WRITE PROTECTION ATTRIBUTE
*
*       U N I F I E D    I / O    C O N T R O L    D E S C R I P T O R
*
*               B L O C K    O F F S E T S
*
CDBIOC  EQU     0               ADDRESS OF IOCB
CDBSDA  EQU     2               SOFTWARE DRIVER ADDRESS
CDBHAD  EQU     4               HARDWARE ADDRESS
CDBDDF  EQU     6               DEVICE DESCRIPTOR FLAGS
CDBVDT  EQU     7               VALID DATA TYPE
CDBDDA  EQU     8               DEVICE DEPENDENT AREA
CDBWST  EQU     10              WORKING STORAGE
*
*       C D B D D F  --  B I T    D E F I N I T I O N S
*
DD$FMC  EQU     %00000001       ASCII-CONVERTED-BINARY IS DEFAULT OBJECT RECORD
DD$LOG  EQU     %00000010       LOGICAL SECTOR I/O FLAG
DD$CNS  EQU     %00000100       CONSOLE FLAG
DD$RWD  EQU     %00001000       REWIND FLAG
DD$OCF  EQU     %00010000       OPEN/CLOSE FLAG
DD$INP  EQU     %00100000       INPUT DEVICE FLAG
DD$OUT  EQU     %01000000       OUTPUT DEVICE FLAG
DD$RES  EQU     %10000000       RESERVABLE DEVICE FLAG
*
*       C D B V D T  --   B I T   D E F I N I T I O N S
*
VD$BIN  EQU     %00000100       BINARY OBJECT FLAG
VD$GDB  EQU     %00001000       TEMP GDB POINTER FLAG
VD$SDA  EQU     %00010000       TEMP SDA POINTER FLAG
VD$NFF  EQU     %10000000       NON-FILE FORMAT FLAG
*
*       D E V I C E    D R I V E R    E N T R Y    O F F S E T S
*
DV$ON   EQU     0               DEVICE ON OFFSET
DV$OFF  EQU     3               DEVICE OFF OFFSET
DV$INT  EQU     6               DEVICE INITIALIZATION OFFSET
DV$TRM  EQU     9               DEVICE TERMINATION OFFSET
DV$IO   EQU     12              DEVICE CHARACTER INPUT/OUTPUT OFFSET
        PAGE
*
*       D I S K    E R O M    E Q U A T E S
*
CURDRV  EQU     0               CURRENT DRIVE NUMBER
STRSCT  EQU     1               STARTING PHYSICAL SECTOR NUMBER
NUMSCT  EQU     3               NUMBER OF SECTORS TO OPERATE UPON
LSCTLN  EQU     5               NUMBERR OF BYTES TO BE READ FROM LAST SECTOR
CURADR  EQU     6               MEMORY ADDRESS FOR DISK TRANSFER
FDSTAT  EQU     8               DISK TRANSFER STATUS
SCTCNT  EQU     11              SECTOR COUNT USED IN DETERMINING ERRORS
PGMDRV  EQU     $1D             DRIVE FROM WHICH LAST PROGRAM WAS LOADED
PGMPSN  EQU     $1E             PHYSICAL SECTOR NUMBER OF RIB OF LAST LOAD PROGRAM
*
*       E R O M    E N T R Y    P O I N T S
*
OSLOAD  EQU     $E800           BOOTSTRAP THE OPERATING SYSTEM
FDINIT  EQU     $E822           INITIALIZE THE DISK'S PIA AND SSDA
CHKERR  EQU     $E853           CHECK AND PRINT ERROR FROM FDSTAT
PRNTER  EQU     $E85A           PRINT ERROR FROM FDSTAT
READSC  EQU     $E869           READ SECTOR(S)
READPS  EQU     $E868           READ PARTIAL SECTOR
RDCRC   EQU     $E86F           READ AND CHECK FOR CRC
RWTEST  EQU     $E872           READ/WRITE TEST
RESTOR  EQU     $E875           MOVE HEAD TO TRACK 0
SEEK    EQU     $E878           POSITION HEAD TO TRACK OF "STRSCT"
WRTEST  EQU     $E87B           WRITE TEST
WRDDAM  EQU     $E87E           WRITE DELETED DATA MARK
WRVERF  EQU     $E881           WRITE AND VERIFY CRC
WRITSC  EQU     $E884           WRITE SECTOR(S)
*
*       E R O M    E R R O R    E Q U A T E S
*
ER$CRC  EQU     '1              DATA CRC ERROR
ER$WRT  EQU     '2              WRITE PROTECTED DISK
ER$RDY  EQU     '3              DISK NOT READY
ER$MRK  EQU     '4              DELETED DATA MARK ENCOUNTERED
ER$TIM  EQU     '5              TIMEOUT
ER$DAD  EQU     '6              INVALID DISK ADDRESS
ER$SEK  EQU     '7              SEEK ERROR
ER$DMA  EQU     '8              DATA ADDRESS MARK ERROR
ER$ACR  EQU     '9              ADDRESS MARK CRC ERROR
*
*       M I S C E L L A N E O U S    E R O M    E Q U A T E S
*
RETRY$  EQU     5               RETRY COUNT FOR DISK READ/WRITE ERRORS
*
*       L I N E    P R I N T E R    E R O M    E Q U A T E S
*
LPINIT  EQU     $EBC0           INIT PRINTER PIA
LIST    EQU     $EBCC           PRINT CONTENTS OF 'A'
LDATA   EQU     $EBE4           PRINT STRING, CR/LF
LDATA1  EQU     $EBF2           PRINT STRING, NO CR/LF
*
*       E X B U G   E Q U A T E S    F O R    M D O S
*
INCHNP  EQU     $F015           INPUT CHARACTER (NO PARITY)
OUTCH   EQU     $F018           OUTPUT ONE CHARACTER
PCRLF   EQU     $F021           PRINT LF/CR
PDATA   EQU     $F024           PRINT STRING
SBIT$   EQU     $FCFD           BIT 7 INDICATES IRQ OCCURRED (IF CLEARED)
BRKPT$  EQU     $FF1F           MAID'S BREAKPOINT TABLE (8 FDB'S)
BKPIN$  EQU     $FF4F           EXBUG BREAKPOINTS IN MEMORY (FROM CONTINUE CMD)
AECHO   EQU     $FF53           INPUT CHARACTER ECHO FLAG (0=>ECHO)
IRQ$SVC EQU     $FFF8           IRQ VECTOR
SWI$VC  EQU     $FFFA           SWI VECTOR
NMI$VC  EQU     $FFFC           NMI VECTOR
XSTAK$  EQU     $FF8A           EXBUG STACK
MAID$   EQU     $F0F3           MAID ENTRY POINT
XREG$P  EQU     $FF16           MAID P-REG
XREG$X  EQU     $FF18           MAID X-REG
XREG$A  EQU     $FF1A           MAID A-REG
XREG$B  EQU     $FF1B           MAID B-REG
XREG$C  EQU     $FF1C           MAID C-REG
XREG$S  EQU     $FF1D           MAID S-REG
BRKPE$  EQU     $FF63           END OF MAID BREAKPOINT TABLE
CNACI$  EQU     $FCF4           CONSOLE ACIA
*
*       SPECIAL MACRO FOR THE CENTRONIX PRINTERS TO PRINT TITLES
*
*TITLE  MACR
*       TTL     \0
*       ENDM
        page
*
*       IOCBD EQUATES
*
IOCBDIOCBAD     EQU     0       ADDRESS OF THE IOCB
IOCBDCHAN       EQU     2       CHANNEL USED BY THIS IOCB
IOCBDSTAD       EQU     3       STRING WHICH CONTAINS THE DEVICE NAME
IOCBDFILL       EQU     5       FILLER FOR MDOS COMPAT
IOCBDDDF        EQU     6       DDF FLAGS
IOCBDFN EQU     7       FILE NAME FOR FUTURE DELETES...
IOCBDLEN        EQU     37      ADDING UP TO A TOTAL OF 38 BYTES
        page
*
*       MDOS variables known to MDOS user programs
*
        org     $100
        fdb     $3033           VERS$$ (MDOS Version)
        fdb     $FFFF           REVS$$ (MDOS Revision)
        fdb     0               KYI$SV (Save Area for .KEYIN)
        fdb     $2000-1         ENDOS$
        fdb     $2000-1         ENDUS$ (initialized by Startup)
        fdb     $2000-1         ENDSY$ (initialized by Startup)
        fdb     0               (dummy)
        fdb     $e800           RIBBA$
        fdb     $0020           ENDRV$
        fdb     0               GDBA$ (dummy)
        fdb     0               SYERR$
        fdb     swiintercept    SWI$SV
        fdb     notok           SWI$UV
        fdb     0               IRQ$UV
        fdb     0               IRQ$SV
        fdb     0               CHFLG$ (not simulated by MDOSSIM)
        PAGE    FILE NAME PARSER STATE MACHINE DESCIPTION
        ORG     $200            This is where MDOS code starts
BannerStart ; MDOSSIM Banner/Copyright message
        fcc     "MDOS Simulator V"
        fcb     $30+Version,'.,$30+Revision,Assembly,ascii:cr
        fcc     "Copyright (C) 1980 Software Dynamics, Inc."
        fcb     ascii:cr,ascii:cr
BannerEnd equ *
        FDB     EDITDATE        record edit date in case anybody cares
        PAGE    Software Interrupt Interception Routine
SWIINTERCEPT ; SWI FROM MDOS PROGRAM TRANSFERS CONTROL TO HERE
*       INTERRUPTS ARE DISABLED HERE
        TSX
        STX     USERSSTACK             SAVE FOR FAKE TSX'S

        IF     SWIDEBUG                true --> include SWI debug logic
; This logic allows a programmer trying to locate a problem in the
; simulation of some MDOS program to:
;    a) Trace a sequence of MDOS calls, with register displays on each call
;    b) Stop after some fixed number of SWIs has occurred
;    c) Stop when a SWI at a particular address has occurred
;    d) Use SWIs in a debugger to debug code in MDOSSim itself
        LDX    USERSSTACK              is SWI within MDOSSIM itself ?
        LDAA   #$1F
        CMPA   SWI:PC,X
        BHS    WAKEDEBUGGER            yes, go wake the debugger up
        LDX    SWICOUNT                bump # SWI's serviced
        INX                            (displayed in trace information)
        STX    SWICOUNT
        LDX    SWISTOPCOUNT            stop on Nth SWI ?
        BEQ    SWIINT1                 b/ no
        CPX    SWICOUNT                yes, have we hit desired SWI ?
        BEQ    WAKEDEBUGGER            b/ yes, pass control to debugger
SWIINT1 LDX    USERSSTACK              stop on a particular SWI ?
        LDX    SWI:PC,X                (get address of SWI+1)
        CPX    SWISTOPADDRESS
        BEQ    WAKEDEBUGGER            b/ yes, wake the debugger up
        LDS    #MYSTACK                --> DON'T PUSH ANY MORE ON USER STACK
        TST    SWITRACEFLAG            trace SWIs ?
        BEQ    MDOSSWI1                b/ no, go service SWI
        JSR    RDUMP                   yes, do register dump
        BRA    MDOSSWI1

WAKEDEBUGGER ; pass control to system-specific debugger, context block on stack
        LDAA   DEBUGGERENTRY+1         push debugger address onto stack
        PSHA
        LDAA   DEBUGGERENTRY
        PSHA
        LDX    USERSSTACK
        LDX    SWI:REGX,X              restore (A) and (X) to entry values
        LDAA   SWI:REGA,X
        RTS

DEBUGGERENTRY FDB $F807        ; WHERE TO GO FOR DEBUG ($F807 is EXBUG entry)
SWITRACEFLAG FCB  0            ; <>--> DUMP REGISTERS
SWICOUNT   FDB    0            ; NUMBER OF MDOS CALLS SERVICED SO FAR
SWISTOPCOUNT FDB  0            ; <>0 --> STOP WHEN MATCH SWICOUNT
SWISTOPADDRESS FDB 0           ; STOP IF = ADDRESS OF SWI+1

MDOSSWI1
        FIN     SWIDEBUG
        LDX     USERSSTACK             get pointer to user stack area
        IF      M6809
        CLRA
        TFR     A,DP                   Set page zero to zero
        FIN

        LDX     SWI:PC,X               --> USER'S PC/MDOS OP
        LDAA    0,X                    GET MDOS SYSTEM CALL OP
        BITA    #$80                   IS THIS A USER DEFINED OP?
        BNE     USERSWI                YES, PASS TO USER *** INTS DISABLED ***
        CLI                            ALLOW THE SUNSHINE IN...
        LDX     USERSSTACK
        INC     SWI:PC+1,X             ADVANCE PC PAST MDOS OPCODE BYTE
        BNE     SWIINTERCEPT.1
        INC     SWI:PC,X
SWIINTERCEPT.1
        LDX     SWI:REGX,X
        STX     USERX

        TFR     A,B                    MOVE MDOS OP TO (B)
        ASLB                           = FORM BRANCH TABLE INDEX
        CLRA
        IF      M6800!M6801

        ADDD    #SWITABLE
        TDX
        LDX     0,X
        JMP     0,X

        ELSE    (M6809)

        LDX     #SWITABLE
        JMP     [D,X]

        FIN

USERSWI JMP     [SWI$UV]               LET THE USER PROGRAM HANDLE IT
        PAGE    SWI TABLE
SWITABLE        EQU     *

:RESERV FDB     RESERVE
:RELES  FDB     RELEASE
:OPEN   FDB     OPENFILE
:CLOSE  FDB     CLOSE
:GETRC  FDB     GETRECORD
:PUTRC  FDB     PUTRECORD
:REWND  FDB     REWIND
:GETLS  FDB     GETLS
:PUTLS  FDB     PUTLS
:KEYIN  FDB     KEYIN
:DSPLY  FDB     DISPLAY
:DSPLX  FDB     DISPLAX
:DSPLZ  FDB     DISPLAZ
:CKBRK  FDB     ATTENTIONCHECK
:DREAD  FDB     NOTOK
:DWRIT  FDB     NOTOK
:MOVE   FDB     MOVE
:CMPAR  FDB     CMPAR
:STCHB  FDB     STOREBLANKS
:STCHR  FDB     STORECHAR
:ALPAH  FDB     ALPHA
:NUMD   FDB     NUMD
:ADDAM  FDB     ADDAM
:SUBAM  FDB     SUBAM
:MMA    FDB     MMA
:DMA    FDB     DMA
:MDENT  FDB     MDENT
:LOAD   FDB     NOTOK
:DIRSM  FDB     DIRSM
:PFNAME FDB     PARSEFILENAME
:ALUSM  FDB     ALUSM
:CHANG  FDB     NOTOK
:MDERR  FDB     MDOSERR
:ALLOC  FDB     NOTOK
:DEALC  FDB     NOTOK
:EWORD  FDB     SETMDOSERR
:TXBA   FDB     TXBA
:TBAX   FDB     TBAX
:XBAX   FDB     XBAX
:ADBX   FDB     ADBX
:ADAX   FDB     ADAX
:ADBAX  FDB     ADBAX
:ADXBA  FDB     ADXBA
:SUBX   FDB     SUBX
:SUAX   FDB     SUAX
:SUBAX  FDB     SUBAX
:SUXBA  FDB     SUXBA
:CPBAX  FDB     CPBAX
:ASRX   FDB     ASRX
:ASLX   FDB     ASLX
:PSHX   FDB     PUSHX
:PULX   FDB     PULLX
:PRINT  FDB     PRINT
:PRINX  FDB     PRINX
        RPT     $7F-.PRINX             FILL REST OF SWI BRANCH TABLE
        FDB     NOTOK

NOTOK   LDX     #ERR:ILLEGALMDOSCALL
        JMP     ABORT
        PAGE    MDOSSIM Debugging code
        IF      SWIDEBUG
ZERO    EQU     $30
NINE    EQU     $39
LETRA   EQU     $41

PrintChar
        fcb     $c                     ; write ascii
        fcb     printCharend-printChar
        fcb     0,0
        fdb     printChardata
        fdb     1
printCharend    equ     *

printChardata
        fcb     0

PUTC    sta     printchardata
        ldx     #PrintChar
        jsr     syscall
        bcs     exiterror
exiterror
        rts

CRLF    LDA     #CR             DO A CARRIAGE RETURN, LINE FEED
        JSR     PUTCHAR
        LDA     #LF             ECHO LINE FEED

PUTCHAR
        STAA    DUMPSAVA
        STX     DUMPSAVX
        JSR     PUTC
        LDAA    DUMPSAVA
        LDX     DUMPSAVX
        RTS
*
*       PNUMX ---- PRINT NUMBER IN X
*       ASSUMED TO HAVE 4 DIGITS
*

DUMPSAVA   FCB     0
DUMPSAVX   FDB     0
NUMBER     FDB     0

PNUMX   LDAB    #4              PRINT 2 BYTE VALUE IN X
PNUMV   STX     NUMBER          PRINT A VARIABLE # BYTES
        BRA     PNUML

*
*       PNUMA --- PRINT NUMBER IN A
*       ASSUMED TO BE ONE BYTE
*

PNUMA   STAA    NUMBER          STORE VALUE
        LDAB    #2              # DIGITS TO PRINT
PNUML   LDAA    #ZERO/16                THIS REALLY ISN'T MAGIC
        PSHB            SAVE # DIGITS TO PRINT
        LDAB    #4      GET BIT SHIFT COUNT
PNUM2   ASL     NUMBER+1                SHIFT MSB INTO A
        ROL     NUMBER
        ROLA
        DECB            DOWN COUNT BIT SHIFT
        BNE     PNUM2   B/ MORE BITS TO SHIFT
        CMPA    #NINE           > DECIMAL 9?
        BLS     PNUM1           NO, GO PRINT IT...
        ADDA    #LETRA-ZERO-10          YES, CONVERT TO A-F
PNUM1   JSR     PUTCHAR         DISPLAY DIGIT
        PULB            GET DIGIT DISPLAY COUNT BACK
        DECB                    DOWN COUNT # OF DIGITS TO PRINT
        BNE     PNUML           LOOP TILL ALL PRINTED
        RTS                     THEN EXIT

*
*       RDUMP -- DUMP THE REGISTERS
*

DUMPU   FDB     0
DUMPY   FDB     0

RDUMP   JSR     CRLF
        LDX     USERSSTACK      THE U STACK IS GONNA MIMIC THE USER'S STACK
        STX     DUMPU
        IF      M6800
        LDX     #RTABLE6800     THIS DESCRIBES THE FORMAT OF THE DUMP
        FIN
        IF      M6809
        LDX     #RTABLE6809     THIS DESCRIBES THE FORMAT OF THE DUMP
        FIN
        STX     DUMPY

RDUMP.1
        LDX     DUMPY
        LDA     0,X
        INX
        STX     DUMPY
        TSTA
        LBEQ    CRLF
        CMPA    #1
        BNE     RDUMP.1A
        JSR     CRLF
        LDX     DUMPY
        LDA     0,X
        INX
        STX     DUMPY
RDUMP.1A
        JSR     PUTC
        LDA     #'=
        JSR     PUTC
        LDX     DUMPY
        LDA     0,X
        INX
        STX     DUMPY
        TSTA
        BNE     RDUMP.2         B/ TWO BYTE NUMBER
        LDX     DUMPU
        LDA     0,X
        INX
        STX     DUMPU
RDUMP.2D
        JSR     PNUMA
        BRA     RDUMP.4
RDUMP.2
        LDX     DUMPU
        LDX     0,X
        CMPA    #3
        BNE     RDUMP.2C
        LDA     0,X
        BRA     RDUMP.2D
RDUMP.2C
        CMPA    #4
        BNE     RDUMP.2Z
        LDX     SWICOUNT
        BRA     RDUMP.3
RDUMP.2Z
        INC     DUMPU+1
        BNE     RDUMP.2A
        INC     DUMPU
RDUMP.2A
        INC     DUMPU+1
        BNE     RDUMP.2B
        INC     DUMPU
RDUMP.2B
        CMPA    #2
        BNE     RDUMP.3
        LDX     DUMPU
        DEX
        DEX
RDUMP.3 JSR     PNUMX
RDUMP.4 LDA     #SPACE
        JSR     PUTC
        BRA     RDUMP.1

*
*       RTABLE -- DEFINES THE FORMAT OF THE REGISTER DUMP
*

RTABLE6809
        FCB     '#,4
        FCB     'C,0
        FCB     'A,0
        FCB     'B,0
        FCB     'Z,0
        FCB     'X,1
*   IF      NARROWDISPLAY
*        FCB      1
*   FIN
        FCB     'Y,1
        FCB     'U,1
        FCB     '@,3
        FCB     'P,1
        FCB     'S,2
        FCB     0

RTABLE6800
        FCB     '#,4
        FCB     'C,0
        FCB     'B,0
        FCB     'A,0
        FCB     'X,1
        FCB     '@,3
        FCB     'P,1
        FCB     'S,2
        FCB     0
        FIN    SWIDEBUG
        page
*       FILE NAME PARSER
*
*       CURRENT STATE !  AZ  !  09  !   .  !   :  ! TERMINATOR
*       --------------+------+------+------+------+-----------
*       0- ENTRY      !  1   !  1   !  7   !  10  !  12
*       --------------+------+------+------+------+-----------
*       1- PARSE NAME !  2   !  2   !  7   !  10  !  12
*       --------------+------+------+------+------+-----------
*       2- PARSE NAME !  3   !  3   !  7   !  10  !  12
*       --------------+------+------+------+------+-----------
*       3- PARSE NAME !  4   !  4   !  7   !  10  !  12
*       --------------+------+------+------+------+-----------
*       4- PARSE NAME !  5   !  5   !  7   !  10  !  12
*       --------------+------+------+------+------+-----------
*       5- PARSE NAME !  5.1 !  5.1 !  7   !  10  !  12
*       --------------+------+------+------+------+-----------
*       5.1-PARSE     !  5.2 !  5.2 !  7   !  10  !  12
*       --------------+------+------+------+------+-----------
*       5.2-PARSE     ! 6    ! 6    !  7   !  10  !  12
*       --------------+------+------+------+------+-----------
*       6- END NAME   ! ERR  ! ERR  !  7   !  10  !  12
*       --------------+------+------+------+------+-----------
*       7- HANDLE DOT !  8   ! ERR  ! ERR  !  ERR !  12
*       --------------+------+------+------+------+-----------
*       8- SUFFIX     !  9   ! ERR  ! ERR  !  10  !  12
*       --------------+------+------+------+------+-----------
*       9- END SUFFIX ! ERR  ! ERR  ! ERR  !  10  !  12
*       --------------+------+------+------+------+-----------
*       10-HANDLE :   ! ERR  ! 11   ! ERR  ! ERR  !  ERR
*       --------------+------+------+------+------+-----------
*       11-DEVICE #   ! ERR  ! ERR  ! ERR  ! ERR  !  12
*       --------------+------+------+------+------+-----------
*       12-FINAL STATE! ***  ! ***  ! ***  ! ***  !  ***
*       --------------+------+------+------+------+-----------
*
        PAGE    STATE MACHINE DEFINITIONS
::      SET     *
        ORG     0

*       STATE ENTRY
SE:AZNEXTSTATE     RMB  2              WHERE TO GO ON A 'A..'Z
SE:AZCHARDEST      RMB  1              WHERE TO PUT THE CHAR (RELATIVE TO BEGINING OF PACKET)
SE:09NEXTSTATE     RMB  2              WHERE TO GO ON A '0..'9
SE:09CHARDEST      RMB  1              WHERE TO STICK CHARACTER
SE:PERIODNEXTSTATE RMB  2              NEXT STATE ON PERIOD
SE:COLONNEXTSTATE  RMB  2              NEXT STATE ON ':

NOWHERE            EQU  -1
UNDEFINEDSTATE     EQU  0

        ORG     ::
        PAGE    STATE MACHINE BLOCKS

STATE0  FDB     STATE1                 AZ
        FCB     1                      CHARACTER INTO BYTE 1
        FDB     UNDEFINEDSTATE         09
        FCB     NOWHERE
        FDB     UNDEFINEDSTATE
        FDB     UNDEFINEDSTATE

STATE1  FDB     STATE2
        FCB     2
        FDB     STATE2
        FCB     2
        FDB     STATE7
        FDB     STATE10

STATE2  FDB     STATE3
        FCB     3
        FDB     STATE3
        FCB     3
        FDB     STATE7
        FDB     STATE10

STATE3  FDB     STATE4
        FCB     4
        FDB     STATE4
        FCB     4
        FDB     STATE7
        FDB     STATE10

STATE4  FDB     STATE5
        FCB     5
        FDB     STATE5
        FCB     5
        FDB     STATE7
        FDB     STATE10

STATE5  FDB     STATE5.1
        FCB     6
        FDB     STATE5.1
        FCB     6
        FDB     STATE7
        FDB     STATE10
STATE5.1
        FDB     STATE5.2
        FCB     7
        FDB     STATE5.2
        FCB     7
        FDB     STATE7
        FDB     STATE10

STATE5.2
        FDB     STATE6
        FCB     8
        FDB     STATE6
        FCB     8
        FDB     STATE7
        FDB     STATE10


STATE6  FDB     UNDEFINEDSTATE
        FCB     NOWHERE
        FDB     UNDEFINEDSTATE
        FCB     NOWHERE
        FDB     STATE7
        FDB     STATE10

STATE7  FDB     STATE8
        FCB     9
        FDB     UNDEFINEDSTATE
        FCB     NOWHERE
        FDB     UNDEFINEDSTATE
        FDB     UNDEFINEDSTATE

STATE8  FDB     STATE9
        FCB     10
        FDB     UNDEFINEDSTATE
        FCB     NOWHERE
        FDB     UNDEFINEDSTATE
        FDB     UNDEFINEDSTATE

STATE9  FDB     UNDEFINEDSTATE
        FCB     NOWHERE
        FDB     UNDEFINEDSTATE
        FCB     NOWHERE
        FDB     UNDEFINEDSTATE
        FDB     STATE10

STATE10 FDB     UNDEFINEDSTATE
        FCB     NOWHERE
        FDB     STATE11
        FCB     0
        FDB     UNDEFINEDSTATE
        FDB     UNDEFINEDSTATE

STATE11 FDB     UNDEFINEDSTATE
        FCB     NOWHERE
        FDB     UNDEFINEDSTATE
        FCB     NOWHERE
        FDB     UNDEFINEDSTATE
        FDB     UNDEFINEDSTATE

        PAGE    MDOS File Name parser
PARSEFILENAME
        LDX     #STATE0
        STX     CURRENTSTATE
        CLR     RETURNEDSTAT

NEXT    JSR     ISAZ                   A..Z?
        BNE     NEXT1
        LDX     CURRENTSTATE
        LDAA    SE:AZCHARDEST,X
        LDX     SE:AZNEXTSTATE,X
        BRA     ADVANCE

NEXT1   JSR     IS09                   0..9?
        BNE     NEXT2
        LDX     CURRENTSTATE
        LDAA    SE:09CHARDEST,X
        LDX     SE:09NEXTSTATE,X
        BRA     ADVANCE

NEXT2   CMPB    #'.
        BNE     NEXT3
        LDX     CURRENTSTATE
        LDAA    #NOWHERE               DON'T SAVE THE PERIOD
        LDX     SE:PERIODNEXTSTATE,X
        BRA     ADVANCE

NEXT3   CMPB    #':     DEVICE NUMBER?
        BNE     ENDPARSE
        LDX     CURRENTSTATE
        LDAA    #NOWHERE
        LDX     SE:COLONNEXTSTATE,X
        PAGE
ADVANCE STX     CURRENTSTATE
        CMPA    #NOWHERE               IF = , DON'T STICK THE CHARACTER ANYWHERE
        BEQ     ADVANCE2

        PSHB
        TFR     A,B
        CLRA
        LDX     USERX
        ADDD    PACKETP,X
        TDX
        PULB
        STAB    0,X

ADVANCE2
        LDX     CURRENTSTATE
        CPX     #UNDEFINEDSTATE
        BNE     NEXT

ENDPARSE
        LDX     USERSSTACK
        LDAA    LASTCHAR
        STAA    SWI:REGA,X
        LDAB    RETURNEDSTAT
        TPA
        STAB    SWI:REGB,X
        STAA    SWI:REGC,X
        LDX     USERX
        LDD     PACKETP,X
        ADDD    #11                    *** see MDOS manual
        STD     PACKETP,X
        JMP     FAKEANRTI
        PAGE
ISAZNOTEDEVICE ; note that device specifier given
        LDAA    #4
        STAA    RETURNEDSTAT
;       BRA     ISAZ

ISAZ    LDX     USERX
        INC     SCANP+1,X
        BNE     ISAZ2
        INC     SCANP,X
ISAZ2   LDX     SCANP,X                 fetch next character of file name
        LDB     0,X
        CMPB    #$20                    blank ?
        BNE     ISAZ2A                  b/ no
        TST     RETURNEDSTAT            yes, 'start of device name' already seen?
        BNE     ISAZ2A                  b/ yes, blank terminates name
        LDX     CURRENTSTATE            in state 0 ?
        CPX     #STATE0                 ...?
        BEQ     ISAZ                    b/ yes, skip past blanks
ISAZ2A  STAB    LASTCHAR
        CMPB    #'#
        BNE     ISAZ3                   b/ not 'start of device name' char
        LDX     CURRENTSTATE            found at start of file name ?
        CPX     #STATE0
        BEQ     ISAZNOTEDEVICE
ISAZ3   CMPB    #'A
        BLO     NO
        CMPB    #'Z
        BLS     YES
        CMPB    #'A+32
        BLO     NO
        CMPB    #'Z+32
        BLS     YES

NO      LDAA    #1
        RTS

IS09    CMPB    #'0
        BLO     NO
        CMPB    #'9
        BHI     NO

YES     LDAA    #0
        RTS
        PAGE    ATTENTION CHECK
ATTENTIONCHECK
        LDX     #CHECKATTN
        JSR     SYSCALL
        BCC     NOATTN
        LDX     USERSSTACK
        JMP     RETURNCSET

NOATTN  LDX     USERSSTACK
        JMP     RETURNCCLR
        PAGE    CLOSE FILE CALL
CLOSE   LDX     USERX
        LDAA    IOCDTT,X               DELETE?
        ANDA    #%100
        BNE     MAYBEDEL               MIGHT BE...

DOCLOSE BSR     REALCLOSE
DORTI1  JMP     RETURNZ1C0B0           BYE...

REALCLOSE ; the "real" close routine
        LDX     USERX
        LDX     IOCGDW,X
        STX     IOCDAD
        LDX     IOCBDIOCBAD,X
        CPX     USERX                  IS THIS FCB FOR REAL?
        BNE     DORTS                  NO, SO GIVE UP
        JSR     PURGEBUFFER            WRITE OUT ANY REMAINING DATA
        LDX     IOCDAD
        LDAA    IOCBDCHAN,X
        STAA    CLOSEBLOCK+SCBLK:PARAMS CHANNEL #
        LDX     #CLOSEBLOCK
        JSR     SYSCALL                HELLO SDOS
        BCC     RC2
        JMP     ERROR                  WHO WILL CLEAN UP FOR US...

RC2     LDX     USERX
        LDAA    IOCDTT,X
        ORAA    #%10000                FILE CLOSED
        STAA    IOCDTT,X
        CLR     IOCSTA,X
DORTS   RTS
        PAGE
MAYBEDEL ; might be delete-when-close
        LDX     USERX
        LDX     IOCMLS,X               MAX LOG SECTOR...
        INX                            =-1?
        BNE     DOCLOSE                NO, DO DON'T DELETE

DELETE  BSR     REALCLOSE              CLOSE FILE BEFORE DELETE
        LDX     USERX
        LDX     IOCGDW,X               GET PTR TO IOCBD
        LEAX    IOCBDFN,X              (X)=START OF FILE NAME
        STX     DELETEBLOCK+SCBLK:WRBUF
        LDX     #30                    *** SEE MDOS MANUAL (?)
        STX     DELETEBLOCK+SCBLK:WRLEN
        LDX     #DELETEBLOCK
        JSR     SYSCALL
        BCC     DORTI1
        JMP     ERROR                  OOPS!
        PAGE    RELEASE IOCB
RELEASE LDX     USERX
        LDX     IOCGDW,X
        STX     IOCDAD
        LDX     IOCBDIOCBAD,X
        CPX     USERX                  SAME?
        BNE     DORTI                  NO...TURKEY USER

        LDX     #IOCBDTEND
FINDEMPTY
        TST     0,X                    INSERT IOCBD BACK ON FREE LIST
        BRA     GOTIT
        TST     1,X
        BNE     GOTIT
        DEX
        DEX
        BRA     FINDEMPTY
GOTIT
        LDD     IOCDAD
        STD     0,X

        LDX     USERX
        CLR     IOCGDW,X
        CLR     IOCGDW+1,X
        CLR     IOCSTA,X
        LDAA    IOCLUN,X
        ANDA    #%10111111
        STAA    IOCLUN,X
DORTI   JMP     RETURNZ1C0B0
        PAGE    OPEN FILE
OPENFILE ; MDOS .OPEN CALL
        LDX     USERX
        CLR     UPDATEFDF
        LDAA    IOCDTT,X
        ANDA    #%11
        BEQ     UPDATEONLY
        DECA
        BEQ     INPUT
        DECA
        BEQ     OUTPUT

UPDATE  BSR     OPEN
        BCS     TRYCREATE
        JMP     INPUTEXIT

TRYCREATE
        CPX     #ERR:FILENOTFOUND
        BNE     ERROR
        PAGE
OUTPUT  BSR     CREATE
INPUTEXIT
        LDX     USERX
        CLR     IOCSTA,X
        LDAA    IOCDTT,X
        ANDA    #%11101111
        STAA    IOCDTT,X
        LDD     #$FFFF
        STD     IOCMLS,X
        STD     IOCSLS,X
        CLR     IOCLSN,X
        CLR     IOCLSN+1,X
        CLR     IOCSBP,X
        CLR     IOCSBP+1,X
        TST     UPDATEFDF
        BNE     IE2
        LDD     IOCSUF,X
        JSR     SUFFIXTYPES
        LDX     USERX
        ORAA    IOCFDF,X
        STAA    IOCFDF,X
        LDD     #$7FFF
        ; We should get actual file size in 128 byte chunks and place it
        ; here, however, using a large constant works well enough.
        ; IOMDOS attached to the SD BASIC Compiler that runs under MDOS
        ; assumes that if the sign bit of this value is set, that EOF has
        ; been reached, so the largest constant we can get away with is $7FFF.
        ; 32767 sectors of 128 bytes is good for files up to 4mB, good enuf.
        STD     IOCEOF,X
IE2     JMP     RETURNZ1C0B0
        PAGE
CREATE  BSR     MAKEFILENAME
        INC     UPDATEFDF
        STX     CREATEBLOCK+SCBLK:WRLEN
        STAA    CREATEBLOCK+SCBLK:PARAMS
        LDX     #CREATEBLOCK
        JSR     SYSCALL
        BCS     ERROR
        RTS

ERROR   JMP     DOERROREXIT

OPEN    BSR     MAKEFILENAME
        STX     OPENBLOCK+SCBLK:WRLEN
        STAA    OPENBLOCK+SCBLK:PARAMS
        LDX     #OPENBLOCK
        JMP     SYSCALL

UPDATEONLY      EQU     *
INPUT   BSR     OPEN
        BCS     ERROR
        BRA     INPUTEXIT
        PAGE
MAKEFILENAME
        LDX     USERX
        LDX     IOCGDW,X
        STX     IOCDAD
        LDX     IOCBDSTAD,X
        STX     SOURCE
        IF      M6800!M6801

        LDX     #FILENAMEBUF
        STX     DEST
COPYDEVICE
        LDX     SOURCE
        LDA     ,X+
        STX     SOURCE
        LDX     DEST
        STA     ,X+
        STX     DEST
        CMPA    #':
        BNE     COPYDEVICE
        LDX     USERX
        LDAB    #8
        STX     SOURCE

COPYNAME
        LDX     SOURCE
        LDAA    IOCNAM,X
        INX
        STX     SOURCE
        CMPA    #$20
        BEQ     SKIPSTORE              REMOVE ALL BLANKS FROM NAME
        TSTA
        BEQ     SKIPSTORE              REMOVE ALL NULLS FROM NAME
        LDX     DEST
        STA     ,X+
        STX     DEST
SKIPSTORE
        DECB
        BNE     COPYNAME

        ELSE    (M6809)

        LDY     #FILENAMEBUF
        STY     DEST

COPYDEVICE
        LDX     SOURCE
        LDY     DEST
COPYDEVICE1
        LDA     ,X+
        STA     ,Y+
        CMPA    #':
        BNE     COPYDEVICE1
        LDX     USERX
        LDAB    #8
        STX     SOURCE

COPYNAME
        LDX     SOURCE
COPYNAME1
        LDAA    IOCNAM,X
        INX
        CMPA    #ASCII:SPACE
        BEQ     SKIPSTORE              REMOVE ALL BLANKS FROM NAME
        TSTA
        BEQ     SKIPSTORE              REMOVE ALL NULLS FROM NAME
        STA     ,Y+
SKIPSTORE
        DECB
        BNE     COPYNAME1

        FIN

ENDCOPYNAME
        LDX     USERX
        LDD     IOCSUF,X
        IF      M6800!M6801

        LDX     DEST

        ELSE    (M6809)

        TFR     Y,X

        FIN

        STD     1,X
        LDAA    #'.
        STA     ,X+
        LEAX    2,X
        STX     DEST
        LDD     DEST
        SUBD    #FILENAMEBUF
        STD     SOURCE
        LDX     IOCDAD
        BEQ     ENDFILENAME            Donot copy if internal call
        LDAA    SOURCE+1
        IF      M6800!M6801

        STX     TEMPX1
        LDX     #FILENAMEBUF
        STX     TEMPX2
LOOP2   LDX     TEMPX2
        LDB     ,X+
        STX     TEMPX2
        LDX     TEMPX1
        STAB    IOCBDFN,X
        INX
        STX     TEMPX1
        DECA
        BNE     LOOP2
        ELSE    (M6809)

        LDY     #FILENAMEBUF
LOOP2   LDB     ,Y+
        STB     IOCBDFN,X
        INX
        DECA
        BNE     LOOP2
        FIN

        LDX     IOCDAD
        LDAA    IOCBDCHAN,X
ENDFILENAME
        LDX     SOURCE
        RTS
        PAGE    RESERVE IOCB
RESERVE LDX     USERX
        LDX     IOCGDW,X
        CPX     #'D*256+'K
        BEQ     DISK
        CPX     #'C*256+'N
        BNE     NOTCON
        JMP     CONSOLE
NOTCON  CPX     #'L*256+'P
        BNE     BADDEVICE
        JMP     LPT

BADDEVICE ; BAD DEVICE NAME GIVEN BY MDOS PROGRAM
        LDX     #ERR:ILLEGALDEVICE
ABORT   ; (X) CONTAINS ERROR CODE
DOERROREXIT ; SIGNAL ERROR TO USER AND STOP MDOS SIMULATION
        STX     ERROREXITBLOCK+SCBLK:PARAMS
        LDX     #ERROREXITBLOCK
        JMP     SYSCALL                BYE!!!!!

DISK    LDX     USERX
        LDB     IOCLUN,X
        ANDB    #$F                    SO?
        CMPB    #9
        BLS     DISK.2
        ANDB    #7                     FORGET IT...
DISK.2  ASLB
        CLRA
        ADDD    #DISKNAMES
        TDX
        LDX     0,X
        BEQ     BADDEVICE
        LDAA    #DD$LOG!DD$RWD!DD$INP!DD$OUT!DD$OCF
        BRA     FINDFREEIOCBDT
        PAGE
DISKNAMES       EQU     *
        FDB     DISK0
        FDB     DISK1
        FDB     DISK2
        FDB     DISK3
        FDB     DISK4
        FDB     DISK5
        FDB     DISK6
        FDB     DISK7
        FDB     DISK8
        FDB     DISK9

DISK0   FCC     "DISK:"
DISK1   FCC     "WD0::"
DISK2   FCC     "D0:::"
DISK3   FCC     "D1:::"
DISK4   FCC     "D2:::"
DISK5   FCC     "D3:::"
DISK6   FCC     "DS0::"
DISK7   FCC     "DS1::"
DISK8   FCC     "DS2::"
DISK9   FCC     "DS3::"

CONSOLESTR FCC     "CONSOLE:"
LPTSTR     FCC     "LPT:"

CONSOLE LDX     #CONSOLESTR
        LDAA    #DD$CNS!DD$OCF!DD$INP!DD$OUT!DD$FMC
        BRA     FINDFREEIOCBDT

LPT     LDX     #LPTSTR
        LDAA    #DD$OCF!DD$OUT!DD$FMC
*       JMP     FINDFREEIOCBDT
        PAGE
FINDFREEIOCBDT ; FIND FREE IOCB FOR FILE
        STX     STRINGAD
        LDX     #IOCBDT
NEXTIOCBDT
        TST     0,X
        BNE     FOUNDIT
        TST     1,X
        BNE     FOUNDIT
        LEAX    2,X                    SKIP TO NEXT IOCBDT
        BRA     NEXTIOCBDT

FOUNDIT LDB     0,X
        STB     TEMPX
        LDB     1,X
        STB     TEMPX+1
        CLR     0,X
        CLR     1,X
        LDX     TEMPX
        INX
        BEQ     TRYRELIOCBS
        DEX
FOUNDIT2
        STX     IOCDAD
        STAA    CDBDDF,X
        LDD     STRINGAD
        STD     IOCBDSTAD,X
        LDD     USERX
        STD     IOCBDIOCBAD,X
        LDX     USERX
        CLR     IOCSTA,X
        LDAA    #%0001000
        ORAA    IOCDTT,X
        STAA    IOCDTT,X
        LDD     IOCDAD
        STD     IOCGDW,X
        LDAA    #%01000000
        ORAA    IOCLUN,X
        STAA    IOCLUN,X
        JMP     RETURNZ1C0B0
        PAGE
**************************************************************************
*                                                                        *
*     THIS ROUTINE BELOW TRIES TO RECOVER FROM RUNNING OUT OF FREE       *
*     IOCB DESCRIPTORS.  IT  DOES THIS BY CYCLING THROUGH THE IOCBD'S    *
*     CHECKING EACH ONE TO MAKE SURE THAT THE IOCB IT POINTS TO          *
*     STILL POINTS BACK (CHECKIT LOOP).  IF IT FINDS AN IOCBD            *
*     THAT HAS BEEN IGNORED (BUT NOT RELEASED), IT PROCEEDS TO RE-       *
*     CLAIM IT (IGOTONE).  TO DO THIS, IT FIRST TRIES TO CLOSE THE       *
*     CHANNEL [BUT IGNORES ALL CHANNEL IS ALREADY CLOSED ERRORS]         *
*     AND THEN GIVES THE CHANNEL TO THE NEW IOCB.  ANY OTHER TYPE        *
*     ERROR RESULTS IN ABORTING THE PROGRAM.                             *
*                                                                        *
*     THIS STUNT IS NECESSARY BECAUSE MANY MDOS PROGRAMS CHEAT,          *
*     AND SIMPLY REUSE AND IOCB WITHOUT CLOSING IT.                      *
*                                                                        *
**************************************************************************

TRYRELIOCBS ; TRY FOR RECOVER AN IOCB
        LDX     #IOCBD2                -->IOCB1 NEVER USED
CHECKIT STX     DEST
        LDX     IOCBDIOCBAD,X
        LDX     IOCGDW,X
        CPX     TEMPX                  IS HE STILL IN USE?
        BNE     IGOTONE                B/ NO, SO RECYCLE
        LEAX    IOCBDLEN,X
        CPX     #IOCBDEND              ALL OUT?
        BNE     CHECKIT                NO, TRY THE NEXT ONE
TOOMANYIOCBS
        LDX     #ERR:NOMDOSIOCBS
        JMP     ABORT
        PAGE
IGOTONE DEC     IOCBDTEND
        DEC     IOCBDTEND+1            RE-MARK END OF LIST
        LDX     DEST
        PSHA
        LDAA    IOCBDCHAN,X
        STAA    CLOSEBLOCK+SCBLK:PARAMS
        LDX     #CLOSEBLOCK
        JSR     SYSCALL
        BCC     IGOTONE2
        CPX     #ERR:CLOSED            ALREADY CLOSED?
        LBNE    ABORT                  B/ NOPE, GIVE UP!
IGOTONE2
        LDX     DEST
        JMP     FOUNDIT2
        PAGE    REWIND
REWIND  LDX     USERX
        LDX     IOCGDW,X
        STX     IOCDAD
        LDAA    IOCBDCHAN,X
        LDX     IOCBDIOCBAD,X
        CPX     USERX
        BEQ     RW2
        LDX     #ERR:CLOSED
        JMP     ERROR

RW2     STAA    REWINDBLOCK+SCBLK:PARAMS
        JSR     PURGEBUFFER            GET RID OF LAST DATA
        LDX     #REWINDBLOCK
        JSR     SYSCALL
        BCC     RW3
        JMP     ERROR

RW3     LDX     USERX
        CLR     IOCLSN,X
        CLR     IOCLSN+1,X
        CLR     IOCSTA,X
        CLR     IOCSBP,X
        CLR     IOCSBP+1,X
        LDD     #$FFFF
        STD     IOCMLS,X
        LDAA    IOCDTT,X
        ANDA    #\DT$TRU
        STAA    IOCDTT,X
        JMP     RETURNZ1C0B0
        PAGE    DISK IO CALLS FOR SECOND ORDER SIMULATION
DISKOUT EQU     *
*       (X) POINTS TO DATA BUFFER, (B) CONTAINS COUNT
        STX     DKIO:DATA
        STAB    DKIO:CNT
        BEQ     DKORTS
DKO2    LDX     DKIO:DATA              THIS LOOP SHOULD BE FAST
        LDA     ,X+
        STX     DKIO:DATA
        BSR     PUTBYTE
        DEC     DKIO:CNT
        BNE     DKO2
DKORTS  RTS
*
DISKIN  EQU     *
*       (X) POINTS TO DATA BUFFER, (B) CONTAINS COUNT
        STX     DKIO:DATA
        STAB    DKIO:CNT
        BEQ     DKIRTS
DKI2    BSR     GETBYTE
        LDX     DKIO:DATA
        STA     ,X+
        STX     DKIO:DATA
        DEC     DKIO:CNT
        BNE     DKI2
DKIRTS  RTS
        PAGE
PUTBYTE PSHA
        LDX     USERX
        LDX     IOCSBP,X
        BNE     PUTBYTE2
*       BUFFER POINTER IS NOT INITIALIZED, SET IT TO SOMETHING GOOD
        LDX     USERX
        LDD     IOCSBS,X
        STD     IOCSBP,X
        LDX     IOCSBP,X
PUTBYTE2
        PULA
        STA     ,X+
        ADDA    CKSUM
        STAA    CKSUM
        TXD
        LDX     USERX
        STD     IOCSBP,X
        SUBD    IOCSBS,X
        SUBD    #$7F
        IF      M6800!M6801
        BNE     PUTBYTE3
        TSTB
        BEQ     PUTBYTE3
        ELSE
        BLE     PUTBYTE3
        FIN
        JSR     IPUTLS
PUTBYTE3
        LDX     USERX
        LDX     IOCMLS,X
        INX
        BNE     PUTBYTE4               CHECK TO SEE IF WE NEED
        LDX     USERX                  TO SIGNAL NOT TO DELETE FILE AFTER ALL
        LDD     IOCLSN,X
        STD     IOCMLS,X
PUTBYTE4        RTS
        PAGE
GETBYTE LDX     USERX
        LDD     IOCSBS,X
        SUBD    IOCSBP,X               IS SBP<SBS?
        BLS     GETBYTE2
        JSR     GETBYTEGETS2           GET ME THE FIRST SECTOR
GETBYTE2
        LDX     USERX
        LDAA    IOCLSN,X
        CMPA    IOCEOF,X
        BNE     GETBYTE4
        LDAA    IOCLSN+1,X
        CMPA    IOCEOF+1,X
        BNE     GETBYTE4
        JMP     LSREALEOF
GETBYTE4
        LDX     IOCSBP,X
        LDA     ,X+
        PSHA
        TXD
        LDX     USERX
        STD     IOCSBP,X
        SUBD    IOCSBS,X
        SUBD    #$7F
        IF      M6800!M6801
        BNE     GETBYTE3
        TSTB
        BEQ     GETBYTE3
        ELSE
        BLE     GETBYTE3
        FIN
        JSR     GETBYTEGETS            NEXT SECTOR PLEASE!
GETBYTE3
        PULA
        RTS
        PAGE
GETBYTEGETS ; GET ANOTHER SECTOR
        LDX     USERX
        LDD     IOCLSN,X
        ADDD    #1
        STD     IOCLSN,X

GETBYTEGETS2
        CLR     IGNOREEOF
        INC     IGNOREEOF
        JSR     IGETLS
        CLR     IGNOREEOF              CAN'T HANDLE EOF NOW!
        LDX     USERX
        LDD     IOCLSN,X
        SUBD    #1
        STD     IOCLSN,X
        RTS
        PAGE
PURGEBUFFER
        LDX     USERX
        LDAA    IOCDTT,X               SEE IF WE HAVE TO DO THAT PURGE
        ANDA    #DT$OPU
        CMPA    #DT$OPI                ONLY MODE THAT I DON'T HAVE TO
        BEQ     DONTPURGE

        LDD     IOCSBS,X
        SUBD    IOCSBP,X
        BCC     DONTPURGE              UN-INITIALIZED BUFFER IS EMPTY.
        LDAA    IOCDTT,X
        BITA    #DT$SIO                SECTOR I/O ?
        BNE     DONTPURGE

        LDB     IOCSBE+1,X             COMPUTE NUMBER OF BYTES TO ZAP
        SUBB    IOCSBP+1,X             ASSUMES AREA < 256 BYTES
        INCB                           ADJUST FOR CLEAR INCLUSIVE
        LDX     IOCSBP,X
ZEROLOOP ; ZERO PAD THE REST OF THE SECTOR (?)
        CLR     ,X+
        DECB
        BNE     ZEROLOOP
; DUMP PURGED SECTOR BUFFER TO DISK
        JSR     IPUTLS
DONTPURGE
        RTS
        PAGE    PUT RECORD
PUTRECORD
        LDX     USERX
        LDX     IOCGDW,X
        STX     IOCDAD
        LDX     IOCBDIOCBAD,X
        CPX     USERX
        BNE     JGRERR
        LDX     USERX
        LDAA    IOCFDF,X
        ANDA    #%111
        CMPA    #3
        BEQ     PUTBINARYRECORD
        CMPA    #5
        LBEQ    PUTASCIIRECORD
        CMPA    #7
        BEQ     PUTBINARYRECORD

JGRERR  JMP     GRERR
        PAGE
PUTBINARYRECORD
        LDAA    #'D                    RECORD HEADER...
        JSR     PUTBYTE                PUT TO OUTPUT
        CLR     CKSUM
        LDX     USERX
        LDAA    IOCDBE+1,X
        SUBA    IOCDBS+1,X
        INCA                           MODULO 256 ARITHMETIC
        INCA                           ADD 1 FOR CHECKSUM...
        STAA    BYTE
        JSR     PUTBYTE                BYTE COUNT...

PBR2    LDX     USERX
        LDX     IOCDBS,X
        LDAB    BYTE
        DECB
        JSR     DISKOUT                WRITE THAT DATA!
        LDAA    CKSUM
        NEGA
        JSR     PUTBYTE                WRITE THE CHECK SUM
        LDAA    #ASCII:CR
        JSR     PUTBYTE

PBR3    LDX     USERX
        CLR     IOCSTA,X
        LDD     IOCDBE,X
        STD     IOCDBP,X
        JMP     RETURNZ1C0B0
        PAGE    GET TYPE OF FILE (DISK OR OTHERWISE)
GETTYPE LDX     USERX
        LDX     IOCGDW,X
        LDAA    IOCBDCHAN,X
        STAA    GETDEVICETYPE+SCBLK:PARAMS
        STAA    GETCURPOS+SCBLK:PARAMS
        LDX     #GETDEVICETYPE
        JSR     SYSCALL
        BCS     ERRORJ
        LDAA    TYPE
        CMPA    #DVTYP.FILE
        RTS
ERRORJ  JMP     ERROR
        PAGE
PUTASCIIRECORD
        LDX     IOCDAD
        LDAA    IOCBDCHAN,X
        STAA    WRITEABLOCK+SCBLK:PARAMS
        STAA    WRITECR+SCBLK:PARAMS
        LDX     USERX
        LDX     IOCDBS,X
        STX     WRITEABLOCK+SCBLK:WRBUF
        LDX     USERX
        LDX     IOCDBE,X
        LDAA    0,X
        CMPA    #ASCII:CR
        BNE     PARALL
        LDX     USERX
        LDD     IOCDBE,X
        SUBD    IOCDBS,X
        STD     WRITEABLOCK+SCBLK:WRLEN
        BRA     PAR2
PARALL  LDX     USERX
        LDD     IOCDBE,X
        SUBD    IOCDBS,X
        STD     WRITEABLOCK+SCBLK:WRLEN
        LDX     WRITEABLOCK+SCBLK:WRLEN
        INX
        STX     WRITEABLOCK+SCBLK:WRLEN

PAR2    JSR     GETTYPE                IF DISK, USE OWN ROUTINES...
        BEQ     PARUSEDKIO
        LDX     #WRITEABLOCK
        JSR     SYSCALL
        BCC     PAR3
        JMP     ERROR

PAR3    LDX     #WRITECR
        JSR     SYSCALL
        LBCC    PBR3
        JMP     ERROR
        PAGE
PARUSEDKIO
        LDX     WRITEABLOCK+SCBLK:WRBUF
        LDAB    WRITEABLOCK+SCBLK:WRLEN+1
        JSR     DISKOUT
        LDAA    #ASCII:CR
        JSR     PUTBYTE
        JMP     PBR3
        PAGE    GET RECORD
GETRECORD
        LDX     USERX
        LDAA    IOCFDF,X
        ANDA    #7
        CMPA    #3
        BEQ     GETBINARYRECORD
        CMPA    #5
        BEQ     JGETASCIIREC
        CMPA    #7
        BEQ     GETBINARYRECORD

GRERR   LDX     #USERX
        LDAA    #I$DTYP
        STAA    IOCSTA,X
        JMP     FAKEANRTI

JGETASCIIREC    JMP     GETASCIIRECORD

GBOOPS  CPX     #ERR:EOFHIT
        BNE     GBRER
        LDX     USERX
        LDAA    #I$EOF
        STAA    IOCSTA,X
        LDX     USERSSTACK
        STAA    SWI:REGB,X
        SEC
        TPA
        STAA    SWI:REGC,X
        JMP     FAKEANRTI

GBRER   JMP     ERROR
        PAGE
GETBINARYRECORD
        JSR     GETBYTE
        CMPA    #'D                    START OF RECORD?
        BNE     GETBINARYRECORD        NO, SHINE IT ON
        CLR     CKSUM
        JSR     GETBYTE
        STAA    BYTE                   GET BYTE COUNT...
        LDX     USERX
        LDX     IOCDBS,X
        LDAB    BYTE
        DECB                           SUBTRACT CKSUM
        JSR     DISKIN                 READ THAT DATA!

GBR3    LDX     USERX
        CLRA
        LDAB    BYTE    
        DECB
        ADDD    IOCDBS,X
        SUBD    #1
        STD     IOCDBP,X
        TDX
        INX
        LDAA    #ASCII:CR
        STAA    0,X
        JSR     GETBYTE                GET CHECKSUM
*       TST     CKSUM
*       BNE     BAD RECORD CHECKSUM...
        JSR     GETBYTE                SHOULD BE = <CR>
        JMP     RETURNZ1C0B0
        PAGE
GETASCIIRECORD
        LDX     IOCDBS,X
        STX     READABLOCK+SCBLK:RDBUF
        LDX     USERX
        LDD     IOCDBE,X
        SUBD    IOCDBS,X
        STD     READABLOCK+SCBLK:RDLEN
        LDX     IOCGDW,X
        LDAA    IOCBDCHAN,X
        STAA    READABLOCK+SCBLK:PARAMS
        JSR     GETTYPE
        BEQ     GARFD
        LDX     #READABLOCK
        JSR     SYSCALL
        LBCS    GBOOPS

GAR2 ; RE-ENTRY POINT FOR GARFDE
        LDX     USERX
        LDD     READABLOCK+SCBLK:RPLEN
        ADDD    IOCDBS,X
        STD     IOCDBP,X
*
*       CONVERT ALL TABS TO A SPACE (SINCE MDOS HATES TABS)
*
        STD     DEST
        LDD     IOCDBS,X
        STD     SOURCE
        LDX     SOURCE
        LDAA    #ASCII:HT
        LDAB    #ASCII:SPACE
CNVTABSTOSP ; LOOP TO CONVERT TABS TO SPACES
        CMPA    0,X
        BNE     CHECKNEXTCH
        STAB    0,X
CHECKNEXTCH
        CPX     DEST
        LBEQ    RETURNZ1C0B0
        INX
        JMP     CNVTABSTOSP
        PAGE
GARFD   EQU     *
*
*       GET ASCII RECORD FROM DISK...
*
        CLR     READABLOCK+SCBLK:RPLEN
        CLR     READABLOCK+SCBLK:RPLEN+1
        LDX     READABLOCK+SCBLK:RDBUF
        STX     TEMPX1

GARFDL  JSR     GETBYTE
        TSTA                           NULL?
        BEQ     GARFDL
        CMPA    #ASCII:CR
        BEQ     GARFDE
        LDX     TEMPX1
        STA     ,X+
        STX     TEMPX1                 PUT BYTE INTO BUFFER
        LDX     READABLOCK+SCBLK:RPLEN
        INX
        STX     READABLOCK+SCBLK:RPLEN
        CPX     READABLOCK+SCBLK:RDLEN
        BNE     GARFDL
        BRA     GAR2                   ALL DONE!

GARFDE  LDX     TEMPX1
        STA     0,X
        LDX     READABLOCK+SCBLK:RPLEN
        INX
        STX     READABLOCK+SCBLK:RPLEN
        JMP     GAR2
        PAGE    LOGICAL SECTOR I/O
GETLS   BSR     CHECKOK                RIGHT MODE FOR THIS?
        BSR     IGETLS                 GET THE SECTOR
        JMP     RETURNZ1C0B0

PUTLS   BSR     CHECKOK
        BSR     IPUTLS
        JMP     RETURNZ1C0B0

IGETLS  LDX     #READSECTOR
        STX     SYSCALLFORLSIO
        BRA     LSIO

IPUTLS  LDX     #WRITESECTOR
        STX     SYSCALLFORLSIO
        BRA     LSIO

CHECKOK LDX     USERX
        LDAA    IOCDTT,X
        BITA    #32
        BNE     CHECKOKRTS
        JMP     GRERR

CHECKOKRTS      RTS
        PAGE
LSIO    LDX     USERX                  LOGICAL SECTOR I/O COMMON CODE
        LDD     IOCLSN,X
        LDX     IOCLSN,X
        INX
        BEQ     CHECKOKRTS
        LDX     #NEWPOS
        STD     1,X
        CLR     0,X
        CLR     3,X                    =>IOCLSN*256
        LSR     0,X                    RIGHT SHIFT, UNSIGNED
        ROR     1,X
        ROR     2,X
        ROR     3,X                    /2=>IOCLSN*128 => BYTE POSITION
        LDX     USERX
        LDD     IOCSBS,X
        LDX     SYSCALLFORLSIO
        STD     SCBLK:WRBUF,X
        STD     SCBLK:RDBUF,X
        LDX     USERX
        LDX     IOCGDW,X
        LDAA    IOCBDCHAN,X
        LDX     SYSCALLFORLSIO
        STAA    SCBLK:PARAMS,X
        STAA    NEWPOSBLOCK+SCBLK:PARAMS
        LDX     #NEWPOSBLOCK
        JSR     SYSCALL
        BCC     LS2.1
        CPX     #ERR:EOFHIT
        BEQ     LS2.1
        JMP     ERROR
LS2.1   LDX     SYSCALLFORLSIO
        JSR     SYSCALL
        BCC     LS3
        CPX     #ERR:EOFHIT
        BEQ     LSEOF
        JMP     ERROR
        PAGE
LS3     LDX     SYSCALLFORLSIO
        CPX     #WRITESECTOR
        BNE     LS3.1
        LDX     USERX
        LDD     IOCLSN,X
        ADDD    #1
        CMPA    IOCEOF,X
        BLT     LS3.1                  ; we can use a signed branch here...
        BGT     LS3.2                  ; because IOCMLS <= $7FFF.
        CMPB    IOCEOF+1,X
        BLO     LS3.1
LS3.2   STD     IOCEOF,X
LS3.1   LDX     USERX
        LDD     IOCLSN,X
        CMPA    IOCMLS,X
        BLT     LS5                    ; we can use a signed branch here...
        BGT     LS6                    ; because IOCMLS <= $7FFF
        CMPB    IOCMLS+1,X
        BLO     LS5
LS6     STD     IOCMLS,X
LS5     INC     IOCLSN+1,X
        BNE     LS4
        INC     IOCLSN,X
LS4     LDD     IOCSBS,X
        STD     IOCSBP,X
        CLR     IOCSTA,X
        RTS
        PAGE
LSEOF   LDX     READSECTOR+SCBLK:RPLEN
        BEQ     LSEMPTYSECTOR
LSEOF2  LDAA    #128
        SUBA    READSECTOR+SCBLK:RPLEN+1 ZERO OUT REST OF SECTOR
        PSHA
        LDD     READSECTOR+SCBLK:RDBUF
        ADDD    READSECTOR+SCBLK:RPLEN
        TDX
        PULA
LSEOFL  CLR     ,X+
        DECA
        BNE     LSEOFL
        JMP     LS3

LSEMPTYSECTOR
        TST     IGNOREEOF              are we ignoring EOF ?
        BEQ     LSREALEOF              b/ no, signal EOF back to application
        LDX     USERX
        LDD     IOCLSN,X
        STD     IOCEOF,X
        BRA     LSEOF2

LSREALEOF
        LDX     USERX
        LDAA    #I$EOF
        STAA    IOCSTA,X
        LDX     USERSSTACK
        STAA    SWI:REGB,X
        SEC
        TPA
        STAA    SWI:REGC,X
        JMP     FAKEANRTI
        PAGE    P R I N T E R   R O U T I N E S
PRINT   LDAA    #ASCII:CR
        BRA     PRINX.1

PRINX   LDAA    #ASCII:EOT
PRINX.1 LDX     USERX
        CLR     COUNT
        CLR     COUNT+1

PRINL   CMPA    0,X
        BEQ     PRINLE
        INX
        INC     COUNT+1
        BNE     PRINL
        INC     COUNT
        BRA     PRINL

PRINLE  STX     LASTCHAR
        LDX     #PRINTERSCBLK
        LDD     COUNT
        STD     SCBLK:WRLEN,X
        LDD     USERX
        STD     SCBLK:WRBUF,X
        JSR     SYSCALL
        LBCS    ERROR
        LDX     USERSSTACK
        LDD     LASTCHAR
        STD     SWI:REGX,X
        JMP     FAKEANRTI
        PAGE    * * * A L L O C A T E   M E M O R Y * * *
ALUSM   LDX     USERSSTACK
        LDAA    SWI:REGB,X             GET USERS REGB
        BEQ     ALUSM:SETTOM
        DECA
        BEQ     ALUSM:ADDTOM

ALUSM:GIMMEALL
        LDX     ENDSY$
        DEX
        LDD     ENDUS$
        STX     ENDUS$
        SUBD    ENDUS$
        COMB
        COMA
        ADDB    #1
        ADDA    #0
        LDX     USERSSTACK
        STD     SWI:REGX,X
RETURNZ1C0B0
        LDX     USERSSTACK
        LDAA    SWI:REGC,X
        TAP
        CLRB                           SETS B=0, Z=1, C=0
        CLC
        TPA
        STA     SWI:REGC,X
        STAB    SWI:REGB,X             SET USER'S (B) TO ZERO...
        JMP     FAKEANRTI
        PAGE
ALUSM:SETTOM
        LDX     USERSSTACK
        LDD     USERX
        CMPD    $FC                    BOTTOM OF SDOS...
        BHS     ALUSM:SETTOPOK
ALUSM:TOOMUCH
        LDX     USERSSTACK
        LDAA    #0
        SEC
        TPA
        STAA    SWI:REGC,X
        LDAA    #1
        STAA    SWI:REGB,X

ALUSM:SETTOPOK
        LDX     USERX
        DEX
        STX     ENDUS$

ALUSM:NORMRTI
        LDX     USERSSTACK
        LDAB    #0
        CLC
        TPA
        STAA    SWI:REGC,X
        STAB    SWI:REGB,X
        LDAA    #$20                   ??? SEE MDOS MANUAL ???
        STAA    SWI:REGX,X
        LDAA    #1
        STAA    SWI:REGX+1,X
        JMP     FAKEANRTI

ALUSM:ADDTOM
        LDX     USERSSTACK
        LDD     USERX
        ADDD    ENDUS$
        CMPA    $FC
        BLO     ALUSM:ADDTOMOK
        BHI     ALUSM:TOOMUCH
        CMPA    $FC+1
        BHI     ALUSM:TOOMUCH

ALUSM:ADDTOMOK
        STD     ENDUS$
        BRA     ALUSM:NORMRTI
        PAGE    MDOS ERROR SIMULATION
SETMDOSERRR
        LDX     USERSSTACK
        LDAB    SWI:REGB,X
        BNE     SME2
        STAB    SYERR$+1
        LDX     USERX
        LDAB    IOCSTA,X
        ADDB    #$40
SME2    LDAA    #8                     FORM SDOS VERSION OF MDOS ERROR CODE
        STD     SETERROR+SCBLK:PARAMS
        LDX     #SETERROR
        JSR     SYSCALL
        BCC     *+2                    TECHNICALLY, SDOS CANNOT GIVE AN ERROR HERE...
        CLC
        TPA
        LDX     USERSSTACK
        STAA    SWI:REGC,X
        RTS                            TOUGH, HUH?

MDOSERR BSR     SETMDOSERRR
        LDX     #DISPERROR
        JSR     SYSCALL
        BCC     *+2
        CLR     WRITECR+SCBLK:PARAMS
        LDX     #WRITECR
        JSR     SYSCALL
        BCS     *+2
        LDX     USERSSTACK
        JMP     RETURNCCLR

SETMDOSERR
        BSR     SETMDOSERRR
        LDX     USERSSTACK
        JMP     RETURNCCLR
        PAGE    DIRECTORY SEARCH, ETC.
DIRSM   LDX     USERSSTACK
        LDAA    SWI:REGB,X
        CMPA    #2
        BEQ     DIRSM:LOOKUP
        CMPA    #4
        LBEQ    DIRSM:CREATE
        CMPA    #8
        LBEQ    DIRSM:OPORCR
        JMP     NOTOK                  I CAN'T DO THE REST

DIRSM:COMMON
        LDX     USERX
        LDAB    0,X
        CMPB    #$A
        BLO     UNITOK
        SUBB    #$30
        CMPB    #$A
        BLO     UNITOK
        JMP     NOTOK
UNITOK
        LEAX    -$A,X                  ADJUST FOR IOCB DISPLACEMENTS
        STX     USERX
        CLRA
        ASLB
        ADDD    #DISKNAMES
        STD     TEMPX
        LDX     TEMPX
        LDX     0,X
        STX     SOURCE
        LDX     #FILENAMEBUF
        STX     DEST
        LDX     #0
        STX     IOCDAD
        JMP     COPYDEVICE             MAKE SDOS FILE NAME


DIRSM:LOOKUP
        JSR     DIRSM:COMMON
        STX     OPENBLOCK+SCBLK:WRLEN
        LDAA    #MYCHAN
        STAA    OPENBLOCK+SCBLK:PARAMS
        LDX     #OPENBLOCK             DOES IT EXIST?
        JSR     SYSCALL
        BCC     DIRSM:LUYES
        CPX     #ERR:FILENOTFOUND
        BEQ     DIRSM:LUNO
        JMP     ABORT
        PAGE
DIRSM:LUNO
        LDX     USERSSTACK
        LDX     SWI:REGX,X
        STX     USERX
        LDX     USERSSTACK
        LDAB    #1
        SEC
        TPA
        STAA    SWI:REGC,X
        STAB    SWI:REGB,X
        LDAA    #$B7
        LDX     USERX
        STAA    17,X                   FUNNY MDOS STUFF (NO KIDDING??)
        JMP     DIRSM:CLOSEUP          NO, I HAVE NO FILES

DIRSM:LUYES
        LDX     USERSSTACK
        LDX     SWI:REGX,X
        STX     USERX
        LDD     9,X                    *** SEE MDOS MANUAL: GET SUFFIX INTO (A,B)
        BSR     SUFFIXTYPES
        LDX     USERX
        STAA    $D,X                   *** SEE MDOS MANUAL: INTO FDF BYTE
        CLC
        LDAB    #0
        TPA
        LDX     USERSSTACK
        STAA    SWI:REGC,X
        STAB    SWI:REGB,X
        JMP     DIRSM:CLOSEUP
        PAGE
SUFFIXUNKNOWN ; SO ASSUME .SA
        LDD     #'S*256+'A
SUFFIXTYPES
        LDX     #SUFFIXTABLE
        BRA     SUFFIXTYPE

SUFFIXTYPEL
        TST     0,X
        BEQ     SUFFIXUNKNOWN
        LEAX    3,X
SUFFIXTYPE
        CMPD    0,X
        BNE     SUFFIXTYPEL
        LDAA    2,X
        RTS

SUFFIXTABLE     FCC     'SA'
        FCB     FD$FMA
        FCC     'AS'    .ASM
        FCB     FD$FMA
        FCC     'BA'    .BAS
        FCB     FD$FMA
        FCC     'TX'    .TXT
        FCB     FD$FMA
        FCC     'LX'    .LX
        FCB     FD$FMB  I THINK (?)
        FCC     'CM'    .CM
        FCB     FD$FML  LOAD RECORD
        FCC     'BN'    .BN
        FCB     FD$FMB  BINARY RECORD
        FCC     'LP'    LPT FILE
        FCB     FD$FMA
        FCC     'RO'
        FCB     3
        RPT     4       EXPANSION SPACE
        FCB     0,0,0
        FCB     0,0,0   END OF TABLE
        PAGE

DIRSM:OPORCR
        JSR     DIRSM:COMMON
        STX     OPENBLOCK+SCBLK:WRLEN
        LDAA    #MYCHAN
        STAA    OPENBLOCK+SCBLK:PARAMS
        LDX     #OPENBLOCK
        JSR     SYSCALL
        BCC     DIRSM:CREATE2
        CPX     #ERR:FILENOTFOUND
        BEQ     DIRSM:CREATE
        JMP     ABORT
        PAGE
DIRSM:CREATE
        JSR     DIRSM:COMMON
        STX     CREATEBLOCK+SCBLK:WRLEN
        LDAA    #MYCHAN
        STAA    CREATEBLOCK+SCBLK:PARAMS
        LDX     #CREATEBLOCK
        JSR     SYSCALL
        LBCS    ABORT
DIRSM:CREATE2 ; ENTRY POINT FOR DIRSM:OPORCR
        LDAB    #0
        CLC
        TPA
        LDX     USERSSTACK
        STAA    SWI:REGC,X
        STAB    SWI:REGB,X

DIRSM:CLOSEUP
        LDAA    #MYCHAN
        STAA    CLOSEBLOCK+SCBLK:PARAMS
        LDX     #CLOSEBLOCK
        JSR     SYSCALL
        BCC     DIRSM:CLOSERTI
DIRSM:CLOSERTI
        JMP     FAKEANRTI
        PAGE    AWFUL MATH STUFF
PUSHX   LDX     USERSSTACK
        LDX     SWI:PC,X
        STX     RETURNAD
        LDD     #PUSHX2
        LDX     USERSSTACK
        STD     SWI:PC,X
        JMP     FAKEANRTI

PUSHX2  STD     TEMPX2
        TXD
        PSHD
        LDD     RETURNAD
        PSHD
        LDD     TEMPX2
        RTS

PULLX   LDX     USERSSTACK
        LDX     SWI:PC,X
        STX     RETURNAD
        LDD     #PULLX2
        LDX     USERSSTACK
        STD     SWI:PC,X
        JMP     FAKEANRTI

PULLX2  STD     TEMPX2
        PULX
        LDD     RETURNAD
        PSHD
        LDD     TEMPX2
        RTS
        PAGE
MOVE    LDX     USERSSTACK
        LDAB    SWI:REGB,X
        LDX     SWI:REGX,X

        IF      M6800!M6801

        LDX     0,X
        STX     TEMPX                  = FROM ADDRESS
        LDX     USERSSTACK
        LDX     SWI:REGX,X
        LDX     2,X
        STX     TEMPX+2                = TO ADDRESS

MOVEL   LDX     TEMPX
        LDA     ,X+
        STX     TEMPX
        LDX     TEMPX+2
        STA     ,X+
        STX     TEMPX+2
        DECB
        BNE     MOVEL

        LDX     USERSSTACK
        LDX     SWI:REGX,X
        LDD     TEMPX
        STD     0,X
        LDD     TEMPX+2
        STD     2,X

        ELSE    (M6809)

        LDY     0,X                    = FROM ADDRESS
;        STY     TEMPX1
        LDU     2,X                    = TO ADDRESS
;        STU     TEMPX2
MOVEL   LDA     ,Y+
        STA     ,U+
        DECB
        BNE     MOVEL
;        LDX     USERSSTACK
        STY     0,X
        STU     2,X
        FIN

        LDX     USERSSTACK
        CLRB
        TPA
        STAA    SWI:REGC,X
        STAB    SWI:REGB,X
        JMP     FAKEANRTI
        PAGE
MDENT   LDX     #EXITCALL
        JSR     SYSCALL
        BCC     *
        BRA     *

TXBA    LDX     USERSSTACK
        LDD     USERX
        STAB    SWI:REGA,X             NOTE: *** MDOS FUNNY CALLS ...
        STAA    SWI:REGB,X             USE (B,A) INSTEAD OF (A,B)
        JMP     FAKEANRTI

TBAX    LDX     USERSSTACK
        LDAA    SWI:REGB,X
        LDAB    SWI:REGA,X
        STD     SWI:REGX,X
        JMP     FAKEANRTI

XBAX    LDX     USERSSTACK
        LDAA    SWI:REGB,X
        LDAB    SWI:REGA,X
        STD     SWI:REGX,X
        LDD     USERX
        STAA    SWI:REGB,X
        STAB    SWI:REGA,X
        JMP     FAKEANRTI
        PAGE
ADBX    LDX     USERSSTACK
        LDAA    SWI:REGC,X
        TAP
        LDD     USERX
        ADDB    SWI:REGB,X
        ADCA    #0
        STD     SWI:REGX,X
        TPA
        STAA    SWI:REGC,X
        JMP     FAKEANRTI

ADAX    LDX     USERSSTACK
        LDAA    SWI:REGC,X
        TAP
        LDD     USERX
        ADDB    SWI:REGA,X
        ADCA    #0
        STD     SWI:REGX,X
        TPA
        STAA    SWI:REGC,X
        JMP     FAKEANRTI
        PAGE
ADBAX   LDX     USERSSTACK
        LDAA    SWI:REGC,X
        TAP
        LDD     USERX
        ADDB    SWI:REGA,X
        ADCA    SWI:REGB,X
        STD     SWI:REGX,X
        TPA
        STAA    SWI:REGC,X
        JMP     FAKEANRTI

ADXBA   LDX     USERSSTACK
        LDAA    SWI:REGC,X
        TAP
        LDD     USERX
        ADDB    SWI:REGA,X
        ADCA    SWI:REGB,X
        STAA    SWI:REGB,X
        STAB    SWI:REGA,X
        TPA
        STAA    SWI:REGC,X
        JMP     FAKEANRTI
        PAGE
SUAX    LDX     USERSSTACK
        LDAA    SWI:REGC,X
        TAP
        LDD     USERX
        SUBB    SWI:REGA,X
        SBCA    #0
        STD     SWI:REGX,X
        TPA
        STAA    SWI:REGC,X
        JMP     FAKEANRTI

SUBX    LDX     USERSSTACK
        LDAA    SWI:REGC,X
        TAP
        LDD     USERX
        SUBB    SWI:REGB,X
        SBCA    #0
        STD     SWI:REGX,X
        TPA
        STAA    SWI:REGC,X
        JMP     FAKEANRTI
        PAGE
SUBAX   LDX     USERSSTACK
        LDAA    SWI:REGC,X
        TAP
        LDD     USERX
        SUBB    SWI:REGA,X
        SBCA    SWI:REGB,X
        STD     SWI:REGX,X
        TPA
        STAA    SWI:REGC,X
        JMP     FAKEANRTI

SUXBA   LDX     USERSSTACK
        LDAA    SWI:REGC,X
        TAP
        LDD     USERX
        SUBB    SWI:REGA,X
        SBCA    SWI:REGB,X
        STAA    SWI:REGB,X
        STAB    SWI:REGA,X
        TPA
        STAA    SWI:REGC,X
        JMP     FAKEANRTI
        PAGE
CPBAX   LDX     USERSSTACK
        LDAA    SWI:REGC,X
        TAP
        LDAA    SWI:REGB,X
        LDAB    SWI:REGA,X
        CMPA    USERX
        BNE     GETCC
        CMPB    USERX+1
GETCC   TPA
        STAA    SWI:REGC,X
THISRTI JMP     FAKEANRTI

ASRX    LDX     USERSSTACK
        LDD     USERX
        ASRD
        STD     SWI:REGX,X
        JMP     FAKEANRTI

ASLX    LDX     USERSSTACK
        LDD     USERX
        ASLD
        STD     SWI:REGX,X
        JMP     FAKEANRTI
        PAGE    CONSOLE I/O CALLS
DISPLAY LDAA    #ASCII:CR
        STAA    ENDCHAR
        CLR     DONTPRINTCR
        BRA     DISPLAYLINE

DISPLAX LDAA    #ASCII:EOT
        STAA    ENDCHAR
        CLR     DONTPRINTCR
        BRA     DISPLAYLINE

DISPLAZ LDAA    #ASCII:EOT
        STAA    ENDCHAR
        CLR     DONTPRINTCR
        INC     DONTPRINTCR

DISPLAYLINE
        LDX     USERX
        LDAA    ENDCHAR

DISPLOOP ; DISPLAY A BYTE AT (X)
        CMPA    0,X
        BEQ     ENDSTRING
        LDAB    0,X
        CMPB    #ASCII:CR
        BHS     DISPLOOP2
        CMPB    #ASCII:BEL
        BEQ     DISPLOOP2
        LDAB    #$FF    RUBOUT
        STAB    0,X     WHICH ISN'T PRINTED
DISPLOOP2
        INX
        BRA     DISPLOOP
        PAGE
ENDSTRING
        TXD
        LDX     USERSSTACK
        STD     SWI:REGX,X
        SUBD    USERX
        STD     WRITESTRING+SCBLK:WRLEN
        LDX     USERX
        STX     WRITESTRING+SCBLK:WRBUF
        CLR     WRITESTRING+SCBLK:PARAMS
        LDX     #WRITESTRING
DSP1    JSR     SYSCALL
        BCC     DSP2
        JMP     ABORT

DSP2    TST     DONTPRINTCR
        BNE     DSP3
        LDX     #PRINTCR
        CLR     SCBLK:PARAMS,X
        INC     DONTPRINTCR
        BRA     DSP1

DSP3    LDX     USERSSTACK
        CLC
        TPA
        STAA    SWI:REGC,X
        JMP     FAKEANRTI
        PAGE    "ARTHRITIC" FUNCTIONS
ADDAM   LDX     USERSSTACK             MADDAM, I'M ADDAM
        LDAB    SWI:REGA,X
        CLRA
        LDX     USERX
        ADDD    0,X
        STD     0,X
        TPA
        LDX     USERSSTACK
        STAA    SWI:REGC,X
        JMP     FAKEANRTI

SUBAM   LDX     USERSSTACK
        LDAB    SWI:REGA,X
        STAB    TEMPX
        LDX     USERX
        LDD     0,X
        SUBB    TEMPX
        SBCA    #0
        STD     0,X
        TPA
        STAA    SWI:REGC,X
        JMP     FAKEANRTI
        PAGE
MMA     LDX     USERSSTACK
        LDAA    SWI:REGA,X
        LDX     USERX

        TSTA
        BEQ     MMAEND

MMALOOP CLC
        ROL     1,X
        ROL     0,X
        DECA
        BNE     MMALOOP

MMAEND  TPA
        LDX     USERSSTACK
        STAA    SWI:REGC,X
        JMP     FAKEANRTI

DMA     LDX     USERSSTACK
        LDAA    SWI:REGA,X
        LDX     USERX

        TSTA
        BEQ     DMAEND

DMALOOP CLC
        ROR     1,X
        ROR     0,X
        DECA
        BNE     DMALOOP

DMAEND  TPA
        LDX     USERSSTACK
        STAA    SWI:REGC,X
        JMP     FAKEANRTI
        PAGE    MORE STRING FUNCTIONS
CMPAR   LDX     USERX

        IF      M6800!M6801
        LDX     0,X
        STX     TEMPX                  = SOURCE TO COMPARE AGAINST
        LDX     USERX
        LDX     2,X
        STX     TEMPX+2                = DESTINATION TO COMPARE TO
        LDX     USERSSTACK
        LDAB    SWI:REGB,X
COMPARELOOP
        LDX     TEMPX
        LDA     ,X+
        STX     TEMPX
        LDX     TEMPX+2
        CMPA    0,X
        BNE     COMPAREDONE
        INX
        STX     TEMPX+2
        DECB
        BNE     COMPARELOOP
COMPAREDONE
        TPA
        LDX     USERSSTACK
        STAA    SWI:REGC,X
        STAB    SWI:REGB,X
        LDX     USERX
        LDD     TEMPX
        STD     0,X
        LDD     TEMPX+2
        STD     2,X

        ELSE    (M6809)
        LDU     0,X                    = SOURCE TO COMPARE AGAINST
        LDY     2,X                    = DESTINATION TO COMPARE TO
        LDX     USERSSTACK
        LDAB    SWI:REGB,X
COMPARELOOP
        LDA     ,U+
        CMPA    ,Y+
        BNE     COMPAREDONE
        DECB
        BNE     COMPARELOOP
        LEAY    1,Y                    TO OFFSET LEAY -1,Y BELOW
COMPAREDONE
        TPA
        LEAY    -1,Y                   MAKE Y POINT TO NON-MATCHING BYTE
        LDX     USERSSTACK
        STAA    SWI:REGC,X
        STAB    SWI:REGB,X
        STU     0,X
        STY     2,X
        FIN
        JMP     FAKEANRTI
        PAGE
STORECHAR
        LDX     USERSSTACK
        LDAA    SWI:REGA,X
STORECHAR2
        LDAB    SWI:REGB,X
        LDX     USERX

STCHRL  STA     ,X+
        DECB
        BNE     STCHRL

        TPA
        LDX     USERSSTACK
        STAB    SWI:REGB,X
        IF      1               PRESERVE CC SO NON-STANDARD MDOS PROGRAMS WORK
        STAA    SWI:REGC,X
        FIN
        JMP     FAKEANRTI

STOREBLANKS
        LDX     USERSSTACK
        LDAA    #ASCII:SPACE
        BRA     STORECHAR2
        PAGE
ALPHA   LDX     USERSSTACK
        LDAA    SWI:REGA,X
        BITA    #$80
        BNE     RETURNCSET
        CMPA    #'A
        BLO     RETURNCSET
        CMPA    #'Z
        BHI     RETURNCSET

RETURNCCLR
        CLC
        TPA
        STAA    SWI:REGC,X
        JMP     FAKEANRTI

NUMD    LDX     USERSSTACK
        LDAA    SWI:REGA,X
        BITA    #$80
        BNE     RETURNCSET
        CMPA    #'0
        BLO     RETURNCSET
        CMPA    #'9
        BHI     RETURNCSET
        SUBA    #'0
        STAA    SWI:REGA,X
        BRA     RETURNCCLR

RETURNCSET
        SEC
        TPA
        STAA    SWI:REGC,X
        JMP     FAKEANRTI
        PAGE    KEYIN
KEYIN   LDX     USERSSTACK
        LDAB    SWI:REGB,X
        CMPB    #255                   ADD 1 FOR <CR> IF LESS THAN 255 BYTES
        ADCB    #0
        LDX     SWI:REGX,X
        STX     READCONSOLE+SCBLK:RDBUF
        STAB    READCONSOLE+SCBLK:RDLEN+1
        LDX     #READCONSOLE
        JSR     SYSCALL
        LBCS    ABORT
        LDX     READCONSOLE+SCBLK:RPLEN
        CPX     READCONSOLE+SCBLK:RDLEN
        BNE     KEYIN3                 B/ REPLY BUFFER IS NOT FULL
        LDD     READCONSOLE+SCBLK:RDBUF
        ADDD    READCONSOLE+SCBLK:RPLEN
        TDX
        LDAA    #ASCII:CR
        STAA    0,X                    MAKE LAST BYTE INTO <CR>
KEYIN3  DEC     READCONSOLE+SCBLK:RPLEN+1
        LDAA    READCONSOLE+SCBLK:RPLEN+1
        LDX     USERSSTACK
        STAA    SWI:REGB,X
        CLC
        TPA
        STAA    SWI:REGC,X
*       JMP     FAKEANRTI
        PAGE    FAKERTI ROUTINE AND SYSCALL ROUTINE
FAKEANRTI
        LDX     USERSSTACK
        TXS
        RTI                            TOUGH!
*
*       THIS IS HERE SO I CAN EASILY INTERCEPT SYSTEM CALLS
*
SYSCALL JMP     $FB
        PAGE    WORKING STORAGE FOR MDOSSIM
ERR:ILLEGALDEVICE   EQU     400
ERR:ILLEGALMDOSCALL EQU     401     ILLEGAL MDOS CALL
ERR:NOMDOSIOCBS     EQU     402     NO FREE MDOS IOCBS

IGNOREEOF       FCB     0              IGNORE EOF ON GET SECTOR CALL
USERSSTACK      FDB     CHANGED
BYTE            FCB     CHANGED
DKIO:DATA       FDB     CHANGED
DKIO:CNT        FCB     CHANGED
CKSUM           FCB     CHANGED

LASTCHAR        FDB     CHANGED        POINTER TO LAST CHAR ON .PRINT
COUNT           FDB     CHANGED
UPDATEFDF       FCB     0

CURRENTSTATE    FDB     CHANGED

TEMPX1          FDB     CHANGED
TEMPX2          FDB     CHANGED

USERX           FDB     CHANGED

RETURNEDSTAT    FCB     CHANGED
STRINGAD        FDB     CHANGED

SYSCALLFORLSIO  FDB     CHANGED
SOURCE          FDB     CHANGED

SCANP           EQU     0
PACKETP         EQU     2
SCANPTR         EQU     0

RETURNAD        FDB     CHANGED

ENDCHAR         FCB     CHANGED
DONTPRINTCR     FCB     CHANGED
IOCDAD          FDB     CHANGED
DEST            FDB     CHANGED

FILENAMEBUF ; FILE NAME BUFFER
        RPT     30
        FCB     CHANGED
        PAGE    IOCBDT STUFF
**********************************************************************
*                                                                    *
*     IOCB DESCRIPTOR:                                               *
*                                                                    *
*          THIS IS A LIST OF IMPORTANT DATA ASSOCIATED WITH EACH     *
*          IOCB THAT THE USER HAS RESERVED.  THE FOLLOWING DATA IS   *
*          KEPT IN EACH IOCBD:                                       *
*                                                                    *
*               IOCBAD       -THE ADDRESS OF THE IOCB WHICH THIS     *
*                             IOCBD IS RESERVED TO                   *
*               CHAN         -THE CHANNEL NUMBER ALL I/O IS TO BE    *
*                             DONE ON WITH THIS IOCB                 *
*               STAD         -THE ADDRESS OF THE DEVICE NAME STRING  *
*                             (TO BE USED ON OPEN'S, ETC.)           *
*               FILL         -FILLER FOR MDOS COMPATABILITY          *
*               DDF          -DDF BYTE SO PROGRAMS CAN LOOK AT THE   *
*                             TYPE OF FILE THEY'VE OPENED            *
*               FILENAME     -THE EQUIVILENT SDOS FILE NAME          *
*                                                                    *
**********************************************************************
        FDB     0
IOCBDT  FDB     0       SINCE CHANNEL 1 IS USED AS 'MYCHAN'
        FDB     0       SINCE CHANNEL 2 IS NOW THE LPT
        FDB     IOCBD3
        FDB     IOCBD4
        FDB     IOCBD5
        FDB     IOCBD6
        FDB     IOCBD7
IOCBDTEND       FDB     -1

IOCBD1  FDB     CHANGED
        FCB     1
        FDB     CHANGED
        FDB     0
        RPT     30
        FCB     CHANGED

IOCBD2  FDB     CHANGED
        FCB     2
        FDB     CHANGED
        FDB     0
        RPT     30
        FCB     CHANGED

IOCBD3  FDB     CHANGED
        FCB     3
        FDB     CHANGED
        FDB     0
        RPT     30
        FCB     CHANGED

IOCBD4  FDB     CHANGED
        FCB     4
        FDB     CHANGED
        FDB     0
        RPT     30
        FCB     CHANGED

IOCBD5  FDB     CHANGED
        FCB     5
        FDB     CHANGED
        FDB     0
        RPT     30
        FCB     CHANGED

IOCBD6  FDB     CHANGED
        FCB     6
        FDB     CHANGED
        FDB     0
        RPT     30
        FCB     CHANGED

IOCBD7  FDB     CHANGED
        FCB     7
        FDB     CHANGED
        FDB     0
        RPT     30
        FCB     CHANGED
IOCBDEND        EQU     *
        PAGE    SYSTEM CALLS
PRINTERSCBLK
        FCB     SYSCALL:WRITEA
        FCB     8
        FCB     2,0
        FDB     0,0

SETERROR
        FCB     SYSCALL:SETERROR
        FCB     SETERROR:SCLEN
        FDB     CHANGED

DISPERROR
        FCB     SYSCALL:DISPERROR
        FCB     DISPERROR:SCLEN

CHECKATTN
        FCB     SYSCALL:ATTNCHECK
        FCB     2

READBYTEBLOCK
        FCB     SYSCALL:READB
        FCB     READB:SCLEN
        FCB     CHANGED,IGNORED
        FDB     IGNORED,IGNORED WRITE BUFFERS
        FDB     CHANGED+IGNORED RPLEN
        FDB     BYTE
        FDB     1

READSECTOR
        FCB     SYSCALL:READB
        FCB     READB:SCLEN
        FCB     CHANGED,IGNORED
        FDB     IGNORED,IGNORED
        FDB     CHANGED+IGNORED
        FDB     CHANGED
        FDB     128     SECTOR SIZE OF FLOPPY
        PAGE
NEWPOSBLOCK
        FCB     SYSCALL:CONTROL
        FCB     8,CHANGED
        FCB     CC:POSITION
        FDB     NEWPOS
        FDB     4

NEWPOS  FCB     CHANGED,CHANGED,CHANGED,CHANGED

REWINDBLOCK
        FCB     SYSCALL:CONTROL
        FCB     8,CHANGED
        FCB     CC:POSITION
        FDB     FOURZEROS
        FDB     4

FOURZEROS
        FCB     0,0,0,0

WRITEBYTEBLOCK
        FCB     SYSCALL:WRITEB
        FCB     WRITEB:SCLEN
        FCB     CHANGED,IGNORED
        FDB     BYTE
        FDB     1

WRITESTRING
WRITEABLOCK
        FCB     SYSCALL:WRITEA
        FCB     WRITEA:SCLEN
        FCB     CHANGED,IGNORED
        FDB     CHANGED,CHANGED
        PAGE
WRITESECTOR
        FCB     SYSCALL:WRITEB
        FCB     WRITEB:SCLEN
        FCB     CHANGED,IGNORED
        FDB     CHANGED
        FDB     128

WRITECR
PRINTCR FCB     SYSCALL:WRITEA
        FCB     WRITEA:SCLEN
        FCB     CHANGED,IGNORED
        FDB     CRSTRING
        FDB     1

CRSTRING FCB    ASCII:CR

EXITCALL
        FCB     SYSCALL:EXIT
        FCB     EXIT:SCLEN

ERROREXITBLOCK
        FCB     SYSCALL:ERROREXIT
        FCB     ERROREXIT:SCLEN
        FDB     CHANGED                ERROR STATUS
        PAGE
CLOSEBLOCK
        FCB     SYSCALL:CLOSE
        FCB     CLOSE:SCLEN
        FCB     CHANGED

CREATEBLOCK
        FCB     SYSCALL:CREATE
        FCB     CREATE:SCLEN
        FCB     CHANGED,IGNORED

        FDB     FILENAMEBUF
        FDB     CHANGED
        FDB     CHANGED
        FDB     NULL4
        FDB     4

NULL4   FDB     CHANGED,CHANGED

DELETEBLOCK
        FCB     SYSCALL:DELETE
        FCB     DELETE:SCLEN
        FCB     CHANGED,IGNORED
        FDB     FILENAMEBUF
        FDB     CHANGED
        FDB     CHANGED
        FDB     NULL4
        FDB     4
        PAGE
GETCURPOS
        FCB     SYSCALL:STATUS
        FCB     STATUS:SCLEN
        FCB     CHANGED
        FCB     SC:GETPOS
        FDB     IGNORED,IGNORED,CHANGED
        FDB     POSBUF
        FDB     4

POSBUF  FDB     CHANGED,CHANGED

OPENBLOCK
        FCB     SYSCALL:OPEN
        FCB     OPEN:SCLEN
        FCB     CHANGED,IGNORED
        FDB     FILENAMEBUF
        FDB     CHANGED
        FDB     CHANGED
        FDB     NULL4
        FDB     4

WRITEBBLOCK
        FCB     SYSCALL:WRITEB
        FCB     WRITEB:SCLEN
        FCB     CHANGED,IGNORED
        FDB     CHANGED,CHANGED
        PAGE
READBBLOCK
        FCB     SYSCALL:READB
        FCB     READB:SCLEN
        FCB     CHANGED
        FCB     IGNORED
        FDB     IGNORED,IGNORED
        FDB     CHANGED
        FDB     CHANGED,CHANGED

READABLOCK
        FCB     SYSCALL:READA
        FCB     READA:SCLEN
        FCB     CHANGED
        FCB     1
        FDB     IGNORED,IGNORED
        FDB     CHANGED
        FDB     CHANGED,CHANGED

READCONSOLE
        FCB     SYSCALL:READA
        FCB     READA:SCLEN
        FCB     0,1
        FDB     IGNORED,IGNORED
        FDB     CHANGED
        FDB     CHANGED,CHANGED

GETDEVICETYPE
        FCB     SYSCALL:STATUS
        FCB     STATUS:SCLEN
        FCB     CHANGED
        FCB     SC:GETTYPE
        FDB     IGNORED,IGNORED,CHANGED
        FDB     TYPE
        FDB     1

TYPE    FCB     CHANGED

        FCB     $FF                    IF NOT $FF, STACK HAS OVERFLOWED...
        RPT     100                    LOTSA SPACE FOR SIMULATOR STACK
        FCB     CHANGED
MYSTACK FCB     CHANGED                INITIAL STACK POINTER FOR SIMULATOR
        PAGE    MDOS SIMULATOR START-UP LOGIC
*
*       STARTUP -- SETS UP MDOS SIMULATOR TO RUN
*       READS "MDOS" COMMAND LINE INTO $80,
*       AND LOADS THE PROGRAM WHOSE NAME IS xxx.cmd WHERE xxx
*       IS THE FIRST THING TYPED ON THE MDOS COMMAND LINE.
*       ALSO SETS THE COMMAND LINE SCAN POINTER AS MDOS WOULD.
*
STARTUP LDX     $FC
        TXS
        DEX
        STX     ENDSY$
        DEX
        STX     ENDUS$
        LDX     #$1FFF  CONVENTIONAL VALUE FOR EXORCISOR MDOS SYSTEMS
        STX     ENDOS$

        LDX     SWI$SV
        STX     SWIVECT   INTO SWI VECTOR (ASSUMED EXORCISOR)
        LDX     #INPUTLINE
        JSR     SYSCALL
        LBCS    ABORT
        LDX     #PRINTBANNER
        JSR     SYSCALL
        LBCS    ABORT
        LDX     #OPENLPT
        JSR     SYSCALL
        LBCS    ABORT

        LDX     #CBUFF$                = START OF COMMAND LINE READ BY .KEYIN
SCANOVERCOMMANDNAME ; SCAN UNTIL END OF COMMAND NAME FOUND
        LDA     ,X+
        CMPA    #ASCII:SPACE
        BEQ     ENDOFCOMMANDNAMEFOUND
        CMPA    #ASCII:CR
        BNE     SCANOVERCOMMANDNAME
ENDOFCOMMANDNAMEFOUND ; CONSTRUCT "commandname.CM" for SDOS to look up
        DEX
        STX     ENDNAME
        LDAA    0,X
        PSHA
        LDAA    1,X
        PSHA
        LDAA    2,X
        PSHA
        LDAA    3,X
        PSHA

        LDAA    #'.
        STAA    0,X
        LDAA    #'C
        STAA    1,X
        LDAA    #'M
        STAA    2,X
        LDAA    #ASCII:CR      FORCE END OF FILE NAME
        STAA    3,X

        LDX     #LOADSC                fetch COMMANDNAME.cmd
        JSR     SYSCALL
        LBCS    ABORT
        LDX     ENDNAME
        PULA
        STAA    3,X
        PULA
        STAA    2,X
        PULA
        STAA    1,X
        PULA
        STAA    0,X
        STX     CBUFP$                 SAVE BUFFER SCAN POINTER
        JMP     [STARTAD]

INPUTLINE
        FCB     SYSCALL:READA
        FCB     READA:SCLEN
        FCB     0
        FCB     1
        FDB     0,0,0
        FDB     CBUFF$                 MDOS COMMAND LINE BUFFER
        FDB     $F0-CBUFF$             $F0 IS SDOS SACRED SPACE

LOADSC  FCB     SYSCALL:LOAD
        FCB     LOAD:SCLEN
        FCB     0,0
        FDB     CBUFF$
        FDB     $F0-CBUFF$
        FDB     0
        FDB     BLOCK4
        FDB     4

BLOCK4  EQU     *
NAMELEN FDB     0
STARTAD FDB     0
ENDNAME FDB     0

PRINTBANNER
        FCB     SYSCALL:WRITEA
        FCB     WRITEA:SCLEN
        FCB     0,0
        FDB     BANNERSTART
        FDB     BANNEREND-BANNERSTART

OPENLPT FCB     SYSCALL:OPEN
        FCB     OPEN:SCLEN
        FCB     $2,$0                  ON CHANNEL 2
        FDB     LPTSTR
        FDB     4
        FDB     0
        FDB     BLOCK4
        FDB     4

        END     STARTUP
