        TITLE   ROM CODE FOR SSB CHIEFTAIN
*       WITH    WI=107,DE=51
*
*       MISCELLANEOUS BOOT DEFS
*
CONTROLD        EQU     'D-'@
*
*       READ PARAMETER BLOCK
*
                ORG     0
WDREADCMD       RMB     1              READ COMMAND
WDLSN           RMB     3              SECTOR NUMBER
WDXFERCOUNT     RMB     1              TRANSFER COUNT
WDCONTROL       RMB     1              CONTROL FIELD
SECTORBASE      RMB     2              WHERE TO PUT IT
NUMBEROFHEADSM1 RMB     1              NUMBER OF HEADS-1 (FOR WINCHESTER)
READBLOCKSIZE   EQU     *
                ORG     WDLSN+1
FDCYL           RMB     1              What cylinder
FDSECTOR        RMB     1              What sector
*
*                                      
*       Equates for SSB Chieftain DCB-4 1791 floppy disk controller
*
SSBIOBUFFER     EQU     $F760 OR $F761 READ OR WRITE 1K BUFFER ON DCB-4
SSBIOBUFADRHI   EQU     $F762          WRITE ADDRESS COUNTER FOR DCB-4 BUFFER
SSBIOBUFADRLO   EQU     $F763          WRITE ADDRESS COUNTER FOR DCB-4 BUFFER
SSBEXTSTATUS    EQU     $F762 OR $F763 READ EXTERNAL STATUS
SSBPIAORA       EQU     $F764          PIA register controlling floppy
SSBPIAORB       EQU     $F765          PIA register controlling floppy
SSBPIACRA       EQU     $F766          PIA register controlling floppy
SSBPIACRB       EQU     $F767          PIA register controlling floppy
SSBWDSTATUS     EQU     $F76C          WD 1791 Status Register
SSBWDCMD        EQU     $F76C          WD 1791 Command Register
SSBWDTRACK      EQU     $F76D          WD 1791 Track Editor
SSBWDSECTOR     EQU     $F76E          WD 1791 Sector Register
SSBWDDATA       EQU     $F76F          WD 1791 Data Register
                PAGE
                ORG     $F400-6*3      place ROM vectors at top of RAM
SWI3JMP         RMB     3
SWI2JMP         RMB     3
FIRQJMP         RMB     3
IRQJMP          RMB     3
SWIJMP          RMB     3
NMIJMP          RMB     3
*
*       BOOT VARIABLES
*
                ORG     $F300
READSECTOR0     RMB     READBLOCKSIZE  READBLOCK FOR TRYBOOT
*
WDRSENRAM       RMB     1              REQUEST SENSE COMMAND
                RMB     1              LUN
                RMB     1              NOT USED
                RMB     1              NOT USED
                RMB     1              NOT USED
                RMB     1              CONTROL FIELD
*
WDRSERRORRAM    RMB     4              REQUEST SENSE ERROR INFO
*
WDADPRAM        RMB     1              ASSIGN DISK PARAMETERS COMMAND
                RMB     1              LUN
                RMB     4              NOT USED
*
WDPARAMSRAM     RMB     1              STEP PULSE WIDTH (3)
                RMB     1              STEP PERIOD (0)
                RMB     1              STEP MODE (0)
WDNUMBEROFHEADS RMB     1              NUMBER OF HEADS-1 (7)
                RMB     2              CYL ADDR-1 (306+13-1)
                RMB     1              REDUCED WRITE CURRENT CYLINDER
                RMB     1              FIXED DISK DRIVE
                RMB     1              SECTORS PER TRACK-1
                RMB     1              RESERVED
*
READYCOUNT      RMB     1              COUNTS # READY UNITS DURING BOOT LOOP
READSECTORADDRESS RMB   2              ADDRESS OF READSECTOR ROUTINE
WDINITCOUNT     EQU     *-READSECTOR0
*
RETRYCOUNT      RMB     1              # RETRIES PERMITTED ON DISK I/O
RUNNINGENCRYPTED RMB    1              RUNNING ENCRYPTED FLAG
WDBOOTCOUNT     RMB     1              FLOPPY BOOT HOLDOFF COUNTER
*
*               CONFIGURATION
*
                IFUND   VAR
VAR             EQU     1
                FIN
                IFUND   WIRE
WIRE            EQU     0
                FIN
                IFUND   SDOSLOADER
SDOSLOADER      EQU     0
                FIN
                IFUND   LISTIDB
LISTIDB         EQU     0
                FIN
                IF      VAR
CONSOLEPORT     EQU     $F7C0          CONSOLE PORT FOR THE VAR/68
LOADPORT        EQU     $F7C2          LOADER PORT FOR THE VAR/68
                ELSE
CONSOLEPORT     EQU     $F7E8          CONSOLE PORT FOR THE VAR/68
LOADPORT        EQU     $F7EA          LOADER PORT FOR THE VAR/68
                FIN
                IF      SDOSLOADER
IDB09CODE       EQU     $4000
                ELSE
IDB09CODE       EQU     $F800
                FIN
IDB09RAM        EQU     *
                LIST    LISTIDB
                INCLUDE IDB09.ASM
                LIST    1
        PAGE    IDB09 I/O ROUTINES
*
*       RETURN INPUT CHAR FROM LOAD PORT IN A, PARITY STRIPPED
*       NO REGISTER RESTRICTIONS
*
READLOAD
        LDX     #LOADPORT
        BRA     GETCHR1
*
*       RETURN INPUT CHAR FROM CONSOLE PORT IN A, PARITY STRIPPED
*       NO REGISTER RESTRICTIONS
*
GETCHAR LDX     #CONSOLEPORT
GETCHR1 LDA     0,X
        RORA
        BCC     GETCHR1
        LDA     1,X
        ANDA    #$7F                   MASK THE PARITY
        IF      WIRE
*
*       CONTROL-@ GIVES CONTROL TO THE REMOTE (TURN OFF WIRE)
*       CONTROL-W GIVES CONTROL TO THE HOST (TURN ON WIRE)
*
        CMPX    #CONSOLEPORT           IS THIS A CONSOLE INPUT?
        BNE     GETCHR2                B/NO
        CMPA    #'W-'@                 TIME FOR WIRE?
        BNE     GETCHR2                B/ NO
WIRE1   LDA     LOADPORT               WIRE LOOP
        RORA                           SOMETHING AT THE LOAD PORT?
        BCC     WIRE2                  B/ NO
        LDA     LOADPORT+1             YES
        STA     CONSOLEPORT+1
WIRE2   LDA     CONSOLEPORT            SOMETHING AT THE CONSOLE PORT?
        RORA
        BCC     WIRE1                  B/ NO
        LDA     CONSOLEPORT+1
        ANDA    #$7F                   YES, SEE IF IT IS THE QUIT CODE
        CMPA    #'@-'@
        BEQ     GETCHR1                B/ YES, CONTROL BACK TO THE DEBUGGER
        STA     LOADPORT+1
        BRA     WIRE1
        FIN     WIRE
*
GETCHR2 RTS
*
*       OPEN THE LOAD PORT
*       NO REGISTER RESTRICTIONS
*
OPENLOAD
        LDA     #DC1
        LDX     #LOADPORT
        BRA     PUTCHR1
*
*       CLOSE THE LOAD PORT
*       NO REGISTER RESTRICTIONS
*
CLOSELOAD
        LDA     #DC3
        LDX     #LOADPORT
        BRA     PUTCHR1
*
*       OUTPUT THE CHAR IN A
*       NO REGISTER RESTRICTIONS
*
PCHAR   LDX     #CONSOLEPORT
PUTCHR1 LDB     0,X
        BITB    #%00000010
        BEQ     PUTCHR1
        STA     1,X
        RTS
*
*       If an escape check were required, this would do the trick
*
*ESCAPECHECK
*       LDA     CONSOLEPORT            IS THERE AN INPUT CHAR?
*       ORA     #2                     MAKES Z BIT CLEAR IF EXIT
*       RORA
*       BCC     ESCCHK1                B/ NO
*       LDA     CONSOLEPORT+1          YES, GET IT
*       ANDA    #$7F                   MASK PARITY
*       CMPA    #ESCAPE
*ESCCHK1 RTS
*
*       Pointer to default user context block passed in X,
*       Sets up context block (optional) and
*       returns pointer to default user context block in X
*       (this way, you can change it if you don't like it where it is)
*       There are no register restrictions
*
INITIALIZE
        LDD     #BOOT
        STD     PREG,X                 SET DEFAULT PROGRAM COUNTER
        CLR     DPREG,X                ENSURE DATA PAGE POINTER IS ZERO
        LDA     #$FF                   TURN OFF ALL THE USER'S INTS
        STA     CCREG,X
*
*       Give ACIA's enough time to finish transmitting current character
*       at slowest baud rate (110) before hitting him over the head
*       with a reset.
*       110 baud = 10 cps = 100ms/char =100000us/char
*       delay time = 100000us
*       delay count = (2mhz*100000us/char)/(cycles/loop) = 25000
*
        LDY     #25000
INIT1   LEAY    -1,Y
        BNE     INIT1
*
*       Reset the ACIA, then set up for 8+1 bits, divide by 64
*
        IF      VAR
        LDD     #$0315
        ELSE
        LDD     #$0316
        FIN
        STA     CONSOLEPORT
        STA     LOADPORT
        STB     CONSOLEPORT
        STB     LOADPORT
*
*       if it is intended that the machine should boot after reset
*       then
*           wait 5 seconds (give operator time to strike ^D, delay
*               in reset code is sufficient)
*           repeat
*               if control-d on console
*               then return to IDB09 via RTS, X pointing to context block
*               try to boot (see TRYBOOT)
*           end
*       else return to IDB09 via RTS, X pointing to context block
*
*       It is intended that the machine should boot after reset
*
        PSHS    DP,X                   SAVE THE CONTEXT BLOCK POINTER
        JSR     TRYBOOT                TRY TO BOOT
        PULS    DP,X,PC                RESTORE THE CONTEXT BLOCK PTR AND RTS
        PAGE    MESSAGES
BOOTINGFROMWINCHESTER
        FCC     /Loading from Winchester... /
        FCB     0
BOOTINGFROMMINIFLOPPY
        FCC     /Loading from Minifloppy... /
        FCB     0
BOOTINGFROMFLOPPY
        FCC     /Loading from Floppy... /
        FCB     0
ERR:DISKNOTREADY
        FCC     /not ready/
        FCB     CR,LF,0
ERR:SEEKTIMEDOUT
        FCC     /seek timed out/
        FCB     CR,LF,0
ERR:READTIMEDOUT
        FCC     /read timed out/
        FCB     CR,LF,0
ERR:SEEKERROR
        FCC     /seek error/
        FCB     CR,LF,0
ERR:READERROR
        FCC     /read error/
        FCB     CR,LF,0
ERR:NOTABOOTDISK
        FCC     /not a load disk/
        FCB     CR,LF,0
ERR:NOBOOTDEVICEREADY
        FCC     /Make disk device ready/
        FCB     CR,LF,0
        PAGE    WINCHESTER DRIVER
WDREADROM
        FCB     C.READ                 READ COMMAND
        FCB     0                      LUN, SECTOR ADDR 2
        FCB     0                      SECTOR ADDR 1
        FCB     0                      SECTOR ADDR 0
        FCB     1                      SECTOR TRANSFER COUNT
        FCB     0                      CONTROL FIELD
*
        FDB     $100                   SECTOR BASE
        FCB     7                      NUMBER OF HEADS-1 (FOR WINCHESTER)
*
WDRSENROM
        FCB     C.RSEN                 REQUEST SENSE COMMAND
        FCB     0                      LUN
        FCB     0                      NOT USED
        FCB     0                      NOT USED
        FCB     0                      NOT USED
        FCB     0                      CONTROL FIELD
*
WDRSERRORROM                           ; REQUEST SENSE DATA
        RMB     4
*
WDADPROM
        FCB     C.ADKP                 ASSIGN DISK PARAMETERS COMMAND
        FCB     %00000000              LUN
        FCB     0                      NOT USED
        FCB     0                      NOT USED
        FCB     0                      NOT USED
        FCB     0                      NOT USED
*
WDPARAMSROM
        FCB     3                      STEP PULSE WIDTH
        FCB     0                      STEP PERIOD
        FCB     0                      STEP MODE
        FCB     1                      NUMBER OF HEADS-1
        FDB     306+13-1               CYL ADDR (+12 SPARES + 1 FOR PARKING)-1
        FCB     128                    REDUCED WRITE CURRENT CYLINDER
        FCB     0                      FIXED DISK DRIVE
        FCB     32-1                   SECTORS PER TRACK-1
        FCB     0                      RESERVED
*
        FCB     0                      READY COUNT
        FDB     WDREAD                 READSECTOR ADDRESS
        PAGE
        SETDPR  $F600
D.PRTCT         EQU     $F6D4          PRIORITY CONTROL
D.DMAEN         EQU     $F6E7          DMA ENABLE LATCH
*
*       HDA-S EQUATES
*
S.DATA          EQU     $F6E4          DATA I/O BUS
S.STAT          EQU     $F6E5          STATUS REGISTER
*
*       HDA-S STATUS REGISTER BIT DEFINITIONS
*
S.BUSY          EQU     %00000001      I/O BUS BUSY
S.RDWR          EQU     %00000010      READ/WRITE
S.CMDA          EQU     %00000100      COMMAND/DATA
S.MSG           EQU     %00001000      MESSAGE
S.INTE          EQU     %00010000      INTERRUPT ENABLE (LATCH)
S.SEL           EQU     %00100000      SELECT (LATCH)
S.INTR          EQU     %01000000      INTERRUPT REQUEST
S.REQ           EQU     %10000000      REQUEST
*
*       HDA-S STATE DEFINITIONS
*
S.SEND          EQU     S.MSG+S.RDWR   SEND COMMAND BYTES
S.WDATA         EQU     S.MSG+S.CMDA+S.RDWR WRITE DATA
S.RDATA         EQU     S.MSG+S.CMDA   READ DATA
S.RSTA          EQU     S.MSG          READ STATUS BYTES
S.DONE          EQU     0              COMMAND SEQUENCE DONE
*
*       OMT 20C CONTROLLER COMMAND LIST
*
C.SENS          EQU     %00000000      SENSE STATUS
C.RZER          EQU     %00000001      RECALIBRATE (RESTORE, WHERE I COME FROM)
C.RSEN          EQU     %00000011      REQUEST SENSE
C.FMTD          EQU     %00000100      FORMAT DRIVE
C.CHKT          EQU     %00000101      CHECK TRACK FORMAT
C.FMTT          EQU     %00000110      FORMAT TRACK
C.FMTB          EQU     %00000111      FORMAT BAD TRACK
C.READ          EQU     %00001000      READ SECTOR(S)
C.INIT          EQU     %00001001      INITIALIZE (RESET)
C.WRIT          EQU     %00001010      WRITE SECTOR(S)
C.SEEK          EQU     %00001011      SEEK
C.AATK          EQU     %00001110      ASSIGN ALTERNATE TRACK
C.COPY          EQU     %00100000      COPY
C.SCEQ          EQU     %01000000      SCAN EQUAL
C.SHEQ          EQU     %01000001      SCAN HIGH OR EQUAL
C.SLEQ          EQU     %01000010      SCAN LOW OR EQUAL
C.DEFN          EQU     %11000000      DEFINE DRIVE LIMITS
C.ADKP          EQU     %11000010      ASSIGN DISK PARAMETERS
C.LOGO          EQU     %11100110      REQUEST LOGOUT
*
*       OMT 20C ERROR TYPES
*
E.TYPE0         EQU     %00000000      TYPE 0 ERROR (DRIVE ERRORS)
E.TYPE1         EQU     %00010000      TYPE 1 ERROR (CONTROLLER ERROR)
E.TYPE2         EQU     %00100000      TYPE 2 ERROR (COMMAND ERRORS)
E.TYPE3         EQU     %00110000      TYPE 3 ERROR (MISC ERRORS)
        PAGE
*
*       SELECT THE TARGET
*
WDSELECT1
        LDA     #$04                   SAY 'DISK NOT READY'
        JMP     ,U
WDSELECT
        LDA     S.STAT                 CHECK TO SEE IF CONTROLLER IS AVAILABLE
        BITA    #S.BUSY
        BEQ     WDSELECT1              B/ IT ISN'T
        LDA     #1                     ASSERT THE CONTROLLER ID
        STA     S.DATA
        LDA     S.STAT                 ASSERT SEL
        ORA     #S.SEL
        STA     S.STAT
        LDB     S.STAT                 CHECK TO SEE THAT CONTROLLER ASSERTS BSY
        BITB    #S.BUSY                ...?
        BNE     WDSELECT1              B/ CONTROLLER DID NOT ASSERT BUSY
        EORA    #S.SEL                 DEASSERT SEL
        STA     S.STAT
        LDB     #6
*
*       SEND THE STANDARD 6-BYTE COMMAND (AFTER TARGET SELECTION)
*       THESE SIGNALS ARE CONSTANT THROUGHOUT THIS SEQUENCE:
*       SEL HIGH, BSY LOW, C/D LOW, I/O HIGH, MSG HIGH
*       FOR EACH BYTE TRANSFER, TARGET ASSERTS (MAKES LOW) REQ,
*       HOST OUTPUTS DATA BYTES, HOST ASSERTS ACK, TARGET RECEIVES
*       DATA BYTES, TARGET DEASSERTS REQ.
*
WDSENDCMD
        BSR     WDLOOPINIT
WDSENDCMD1
        LDA     S.STAT
        LEAY    -1,Y
        BEQ     WDLOOPTIMEDOUT         B/ TIMED OUT
        ANDA    #S.REQ+S.MSG+S.CMDA+S.RDWR+S.BUSY
        CMPA    #S.SEND
        BNE     WDSENDCMD1             B/ REQ NOT ASSERTED
        LDA     ,X+                    OUTPUT A COMMAND BYTE
        STA     S.DATA
        DECB                           DONE YET?
        BNE     WDSENDCMD1             B/ NO
        RTS                            YES, DONE
*
*       SEND DATA BYTES TO THE TARGET. ASSERT TARGET PREVIOUSLY
*       SELECTED, AND THE 6 BYTE COMMAND SEQUENCE HAS BEEN SENT TO TARGET.
*       THESE SIGNALS ARE CONSTANT THROUGHOUT THIS SEQUENCE:
*       SEL HIGH, BSY LOW, C/D HIGH, I/O HIGH, MSG HIGH
*       FOR EACH BYTE TRANSFER, TARGET ASSERTS (MAKES LOW) REQ,
*       HOST OUTPUTS DATA BYTES, HOST ASSERTS ACK, TARGET RECEIVES
*       DATA BYTES, TARGET DEASSERTS REQ.
*
WDSENDDATA
        BSR     WDLOOPINIT
WDSENDDATA1
        LDA     S.STAT
        LEAY    -1,Y
        BEQ     WDLOOPTIMEDOUT         B/ TIMED OUT
        ANDA    #S.REQ+S.MSG+S.CMDA+S.RDWR+S.BUSY
        CMPA    #S.WDATA
        BNE     WDSENDDATA1            B/ REQ NOT ASSERTED
        LDA     ,X+                    OUTPUT A COMMAND BYTE
        STA     S.DATA
        DECB                           DONE YET?
        BNE     WDSENDDATA1            B/ NO
        RTS                            YES, DONE
*
WDLOOPINIT
        LDY     #1000
        RTS
        PAGE
*
*       Start I/O for SSB winchester disk controller
*
WDREAD  PULS    U                      CARRY THE RETURN ADDRESS IN U
        LDA     #$F6
        TFR     A,DP
*       CLR     S.STAT                 DISABLE SASI INTERRUPT
*       CLR     D.PRTCT                DISABLE DMA PART
*       CLR     D.DMAEN                DISABLE DMA ENABLE LATCH
*
*       ASSIGN DISK PARAMETERS IF NUMBER OF HEADS IS DIFFERENT
*
        LDA     NUMBEROFHEADSM1,X      GET THE NEW # HEADS
        CMPA    WDNUMBEROFHEADS-READSECTOR0,X
        BEQ     WDREAD3                B/ SAME PARAMS AS LAST TIME
        STA     WDNUMBEROFHEADS-READSECTOR0,X
        LDX     #WDADPRAM
        JSR     WDSELECT               SEND THE ASSIGN DISK PARAMS COMMAND
*       LDX     #WDDISKPARAMS          SEND THE DISK PARAMETERS
        LDB     #10                    10 BYTES TO SEND
        JSR     WDSENDDATA
        JSR     WDCOMPLETE
        BEQ     WDREAD2                B/ NO TROUBLE
WDREAD1 JSR     WDGETERROR
        JMP     ,U
WDREAD2 LDX     #READSECTOR0
WDREAD3 BSR     WDSELECT
        LDY     #2924                  6 SEC=12,000,000/4104
WDREAD4 LDA     S.STAT                 (4~) SEE IF CONTROLLER IS BUSY
        ANDA    #S.REQ+S.MSG+S.CMDA+S.RDWR+S.BUSY (2~)
        CMPA    #$8E                   (2~) BUSY?
        BNE     WDREAD5                (3~) B/ NO, GO FINISH UP
        DECB                           (2~)
        BNE     WDREAD4                (3~)
        LEAY    -1,Y                   (5~)+256*(4+2+2+3+2+3)=5+4096
        BNE     WDREAD4                (3~)
WDLOOPTIMEDOUT
        LDA     #$14                   'READ TIMED OUT'
        JMP     ,U
*
WDREAD5 LDB     #256&$FF               READ 256 BYTES
        LDX     ,X                     INTO THIS BUFFER
        BSR     WDREADDATA
        BSR     WDCOMPLETE
        BNE     WDREAD1                B/ ERROR
        CLRA                           SAY 'NO ERRORS'
        JMP     ,U
*
*       WE GOT SOME ERROR, TIME TO FIND OUT WHAT IT IS
*
WDGETERROR
        LDX     #WDRSENRAM             GET ADDRESS OF REQUEST SENSE COMMAND
        BSR     WDSELECT               SELECT THE TARGET AND REQUEST SENSE
*       LDX     #WDRSERRORRAM
        LDB     #4                     GO GET 4 BYTES OF SENSE INFORMATION
        BSR     WDREADDATA
        BSR     WDCOMPLETE             AND FINISH UP
        BEQ     WDGETERROR1            B/ NO ERROR
        STB     WDRSERRORRAM           NOT SUPPOSED TO HAPPEN
WDGETERROR1
        LDA     WDRSERRORRAM           GET THE ERROR
        RTS
*
*       GET DATA BYTES FROM THE TARGET. ASSERT TARGET IS SELECTED.
*       THESE SIGNALS ARE CONSTANT THROUGHOUT THIS SEQUENCE:
*       SEL HIGH, BSY LOW, C/D HIGH, I/O LOW, MSG HIGH
*       FOR STATUS BYTE TRANSFER, TARGET OUTPUTS STATUS BYTE,
*       TARGET ASSERTS (MAKES LOW) REQ, HOST READS STATUS BYTE,
*       HOST ASSERTS ACK, TARGET DEASSERTS REQ.
*
WDREADDATA
        BSR     WDLOOPINIT
WDREADDATA1
        LDA     S.STAT                 SEE IF STATUS BYTE IS READY
        LEAY    -1,Y
        BEQ     WDLOOPTIMEDOUT         B/ TIMED OUT
        ANDA    #S.REQ+S.MSG+S.CMDA+S.RDWR+S.BUSY
        TSTB                           CONTROLLER GIVES US ALL OR NOTHING
        BNE     WDREADDATA2
        CMPA    #S.RSTA                CHECK FOR EARLY DONE (ERROR)
        BEQ     WDREADDATA3            B/ READ STEP SKIPPED BECAUSE OF ERROR
WDREADDATA2
        CMPA    #S.RDATA
        BNE     WDREADDATA1            B/ REQ NOT ASSERTED
        LDA     S.DATA                 READ DATA BYTE
        STA     ,X+
        DECB
        BNE     WDREADDATA1
WDREADDATA3
        RTS
*
*       COME HERE AFTER DATA TRANSFER IS COMPLETE
*       GET STATUS BYTE FROM THE TARGET. ASSERT TARGET IS SELECTED
*       AND THE DATA TRANSFER TO/FROM THE HOST IS COMPLETE.
*       THESE SIGNALS ARE CONSTANT THROUGHOUT THIS SEQUENCE:
*       SEL HIGH, BSY LOW, C/D LOW, I/O LOW, MSG HIGH
*       FOR STATUS BYTE TRANSFER, TARGET OUTPUTS STATUS BYTE,
*       TARGET ASSERTS (MAKES LOW) REQ, HOST READS STATUS BYTE,
*       HOST ASSERTS ACK, TARGET DEASSERTS REQ.
*
WDCOMPLETE
        BSR     WDLOOPINIT
WDCOMPLETE1
        LDA     S.STAT                 SEE IF STATUS BYTE IS READY
        LEAY    -1,Y
        BEQ     WDLOOPTIMEDOUT         B/ TIMED OUT
        ANDA    #S.REQ+S.MSG+S.CMDA+S.RDWR+S.BUSY
        CMPA    #S.RSTA
        BNE     WDCOMPLETE1            B/ REQ NOT ASSERTED
        LDB     S.DATA                 READ STATUS BYTE
*
*       GET MESSAGE BYTE FROM THE TARGET.
*       THESE SIGNALS ARE CONSTANT THROUGHOUT THIS SEQUENCE:
*       SEL HIGH, BSY LOW, C/D LOW, I/O LOW, MSG LOW
*       FOR MESSAGE BYTE TRANSFER, TARGET OUTPUTS MESSAGE BYTE,
*       TARGET ASSERTS (MAKES LOW) REQ, HOST READS MESSAGE BYTE,
*       HOST ASSERTS ACK, TARGET DEASSERTS REQ.
*
WDCOMPLETE2
        LDA     S.STAT                 SEE IF STATUS BYTE IS READY
        LEAY    -1,Y
        BEQ     WDLOOPTIMEDOUT         B/ TIMED OUT
        ANDA    #S.REQ+S.MSG+S.CMDA+S.RDWR+S.BUSY
        CMPA    #S.DONE
        BNE     WDCOMPLETE2            B/ REQ NOT ASSERTED
        LDA     S.DATA                 READ MESSAGE BYTE
*
*       IGNORE THE MESSAGE BYTE (ALL ZEROES)
*       CHECK STATUS BYTE FOR ERROR
*
        BITB    #%00000010             ANY ERRORS?
        RTS
        SETDPR  0
        PAGE    BOOT LOOP
BOOT    BSR     TRYBOOT                TRY TO BOOT
        SWI                            GO ENTER THE DEBUGGER
*
*       SEE IF WE CAN BOOT FROM WINCHESTER
*
TRYBOOT LDA     #15                    ONLY TRY BOOTING FROM WINCHESTER
        STA     WDBOOTCOUNT            FOR FIRST 30 SECONDS
TRYB1   LDX     #READSECTOR0+WDINITCOUNT
        LDU     #WDREADROM+WDINITCOUNT
        LDB     #WDINITCOUNT
TRYB2   LDA     ,-U
        STA     ,-X
        DECB
        BNE     TRYB2
*
*       2-SECOND DELAY (4,000,000~) (SO OPERATOR CAN TYPE ^D)
*
DELAY   LDY     #3105                  3105*(256*5+8)=4000000
DELAY1  DECA                           (2~)
        BNE     DELAY1                 (3~)
        LEAY    -1,Y                   (5~)
        BNE     DELAY1                 (3~)
*
*       CONTROL-D CHECK
*       IF CONTROL-D TYPED, RETURN Z BIT SET
*       ELSE RETURN Z BIT CLEAR
*
CONTROLDCHECK
        LDA     CONSOLEPORT            IS THERE AN INPUT CHAR?
*       ORA     #2                     MAKES Z BIT CLEAR IF EXIT
        RORA
        BCC     CONTROLDCHECK1         B/ NO
        LDA     CONSOLEPORT+1          YES, GET IT
        ANDA    #$7F                   MASK PARITY
        CMPA    #CONTROLD
        BNE     CONTROLDCHECK1
        RTS
CONTROLDCHECK1
*
*       CLR     READYCOUNT
*       LDD     #WDREAD                NAME OF DISK READ ROUTINE TO USE
*       STD     READSECTORADDRESS
*       LDX     #READSECTOR0
        JSR     READSECTOR             TRY TO READ SECTOR 0
*       LDU     #ERR:DISKNOTREADY
        CMPA    #$04                   CHECK READY
        BEQ     TRYB4                  B/ NOT READY
        INC     READYCOUNT             AT LEAST ONE DISK IS READY
        LDU     #BOOTINGFROMWINCHESTER TELL HIM WE'RE ATTEMPTING TO BOOT
        PSHS    A                      SAVE THE ERROR CODE
        JSR     PRINTASCIIZ
        PULS    A                      RESTORE THE ERROR CODE
        LDU     #ERR:SEEKTIMEDOUT
        CMPA    #$02
        BEQ     TRYB3
        LDU     #ERR:READTIMEDOUT
        CMPA    #$14
        BEQ     TRYB3
        LDU     #ERR:SEEKERROR
        CMPA    #$15
        BEQ     TRYB3
        LDU     #ERR:READERROR
        TSTA
        BNE     TRYB3                  ASSUME ALL OTHER
        BSR     SMELLTEST              SEE IF IT LOOKS LIKE A BOOT SECTOR
        BRA     TRYB4                  I GUESS IT'S NOT
TRYB3   BSR     PRINTASCIIZ
TRYB4   DEC     WDBOOTCOUNT
        BPL     TRYB1                  B/ DON'T TRY TO BOOT FROM FLOPPIES
*
*       SEE IF WE CAN BOOT FROM MINIFLOPPIES
*
        BSR     FDSELECT               TRY TO BOOT FROM MINIFLOPPY
        FCB     0                      UNIT NUMBER TO SELECT
        FDB     BOOTINGFROMMINIFLOPPY  TELL HIM WE'RE ATTEMPTING TO BOOT
*
*       SEE IF WE CAN BOOT FROM UNIT 4 (8-INCH FLOPPY)
*
        BSR     FDSELECT               TRY TO BOOT FROM FLOPPY
        FCB     4                      UNIT NUMBER TO SELECT
        FDB     BOOTINGFROMFLOPPY
*
*       IF ALL THE DRIVES WERE NOT READY, SAY 'No Boot device ready'
*
        LDA     READYCOUNT
        BNE     TRYB1                  B/ SOME DRIVE WAS READY
        LDU     #ERR:NOBOOTDEVICEREADY
        BSR     PRINTASCIIZ
        BRA     TRYB1
        PAGE    FD DISK ROUTINES
SETRETRYCOUNT
        LDA     #4
        STA     RETRYCOUNT
*       RTS                            CHEAP TRICK HERE
*
SETDATAPAGE
        LDB     #$F7
        TFR     B,DP
SETDATAPAGERTS
        RTS
*
*       JSR     FDSELECT
*       FCB     UNIT NUMBER
*       FDB     ADDRESS OF BOOT MESSAGE
*
FDSELECT
        PULS    Y                      GET POINTER TO PARAMS
        LDA     ,Y+                    GET UNIT
        COMA                           UNIT NUMBER IS INVERTED
        STA     SSBPIAORB              HEAD LOAD IS DISABLED
        EORA    #$90                   ENABLE HEAD LOAD AND XFER
        STA     SSBPIAORB
        LDU     ,Y++                   GET BOOT MESSAGE POINTER
        PSHS    Y                      NEW RETURN ADDRESS
        LDD     #FDREAD                SETUP SECTOR READ ROUTINE ADDRESS
        STD     READSECTORADDRESS
        BSR     SETRETRYCOUNT
        BSR     FDREADYCHECK           IS THE FLOPPY READY?
        BCS     FDSELECTRTS            B/ IT'S NOT READY
        INC     READYCOUNT             AT LEAST ONE DISK IS READY
        BSR     PRINTASCIIZ
        BSR     FDRESTORE              RESTORE THE FD
        BCS     PRINTASCIIZ            B/ SOME KIND OF ERROR
        LDX     #READSECTOR0
        JSR     READSECTOR
        BCS     PRINTASCIIZ            B/ SOME ERROR ENCOUNTERED WHILE READING
*
SMELLTEST       ; SNIFF THE SECTOR FOR GOOD BOOT CODE
        LDU     #ERR:NOTABOOTDISK      ASSUME IT'S NOT A BOOT DISK
        LDD     #$10CE                 SMELL THE SECTOR FOR A LOAD STACK INST
        CMPD    $100
        BNE     PRINTASCIIZ            B/ DOESN'T SMELL LIKE LOAD STACK TO ME!
        JMP     $100                   GO EXECUTE IT
*
*       PRINTS ASCIIZ MESSAGE POINTED TO BY U
*       AND TERMINATED BY A NULL BYTE
*
PRASCIIZ1
        JSR     PCHAR
PRINTASCIIZ
        LDA     ,U+                    GET NEXT CHAR
        BNE     PRASCIIZ1              B/ GO PRINT IT
FDSELECTRTS
        RTS                            DONE
        PAGE
*
*       This code is here because mini-floppies don't have ready line
*       (unbelievable!!)
*
*       Wait for Disk Ready (change in index hole status)
*
FDREADYCHECK
        BSR     FDDISKABORT            Get type I status
        BPL     FDREADYCHECK2          STATUS SAYS IT'S READY
        LDX     #16666                 LOOK FOR CHANGE IN INDEX HOLE
        LDB     #%00100000             HEAD MUST BE LOADED FOR VALID STATUS
FDREADYCHECK1
        LDA     SSBWDSTATUS
        LEAX    -1,X                   (5~) ARE WE TIMED OUT YET?
        BEQ     FDREADYCHECK3          (3~) B/ YES
        BITB    SSBWDSTATUS            (4~) IS THE HEAD STILL LOADED?
        BEQ     FDREADYCHECK           (3~) B/ NO
        EORA    SSBWDSTATUS            (4~) IS THERE A CHANGE IN INDEX HOLE?
        BITA    #%00000010             (2~)
        BEQ     FDREADYCHECK1          (3~) B/ NO
FDREADYCHECK2
        CLRA                           (CLEAR THE CARRY)
        RTS
FDREADYCHECK3
        LDU     #ERR:DISKNOTREADY
        COMA                           (SET THE CARRY)
        RTS
*
FDRESTORE
        BSR     FDDISKABORT            Kill whatever disk is doing
        LDA     #%00001001             PICK UP A RESTORE COMMAND
        JSR     FDISSUECMD             Go do the restore
        BCS     FDRESTORE1             B/ TIMED OUT ON SEEK
        BITA    #%00000100             Check for arrival at cylinder zero
        BNE     FDRESTORE1             B/ GOT THERE (ASSERT CARRY IS CLEAR)
        DEC     RETRYCOUNT
        BPL     FDRESTORE
        LDU     #ERR:SEEKERROR         ASSUME SEEK ERROR
        COMA                           (SET THE CARRY)
FDRESTORE1
        RTS
        PAGE
WAIT28US
        LDA     #(28*2-7-5)//(2+3)     = # times around loop to make 28 Us.
        DECA                           2 cycles
        BNE     *-1                    3 cycles
        RTS
*
*       Make the controller idle and get status
*       Issue abort command, wait 28us for status to be valid,
*       then read.
*
FDDISKABORT
        LDA     #%11010000             abort with no interrupts
        STA     SSBWDCMD
        BSR     WAIT28US
        LDA     SSBWDSTATUS            return with status in B
*
*       BECAUSE THE DISK SELECT LINES ARE GATED WITH HEAD LOAD,
*       WE CAN ONLY HAVE VALID STATUS WHEN THE HEADS ARE LOADED
*
        BITA    #%00100000             STATUS IS VALID ONLY IF HEAD IS LOADED
        BEQ     FDDISKABORT1           B/ STATUS IS NOT VALID
        TSTA
        RTS
FDDISKABORT1    ; OH, LOOK! THE HEADS ARE NOT LOADED. LOAD THEM!
        LDA     SSBWDTRACK
        STA     SSBWDDATA
        LDA     #%00011001             MAKE HIM SEEK TO SAME TRACK
*
*       Issue the 1791 command in (A)
*
FDISSUECMD
        STA     SSBWDCMD               Tell the 1791 to stick this up his...
        BSR     WAIT28US
        LDY     #0                     USE 1.5 SEC TIMEOUT (65536*48=3145728 CYC)
FDISSUECMD1
        PSHS    CC,A,B,DP,X,Y,U        (15~)
        PULS    CC,A,B,DP,X,Y,U        (15~)
        LEAY    -1,Y                   (5~) HAS THE DISK TIMED OUT?
        BEQ     FDISSUECMD2            (3~) B/ YES
        LDA     SSBEXTSTATUS           (5~) NO, SEE IF DONE
        RORA                           (2~)
        BCC     FDISSUECMD1            (3~) B/ NOT DONE
        CLRA                           (CLEAR THE CARRY)
        LDA     SSBWDSTATUS            GET THE STATUS
        RTS
FDISSUECMD2
        BSR     FDDISKABORT            HE TIMED OUT, TELL HIM TO STOP IT
        LDU     #ERR:SEEKTIMEDOUT
FDISSUECMD3
        COMA                           (SET THE CARRY)
        RTS
        PAGE
*
FDREADERROR
        DEC     RETRYCOUNT
        BPL     READERROR1
        LDU     #ERR:DISKNOTREADY
        BITA    #%10000000             CHECK NOT READY
        BNE     FDISSUECMD3            B/ NOT READY
        LDU     #ERR:SEEKERROR
        BITA    #%00010000             CHECK RECORD NOT FOUND
        BNE     FDISSUECMD3            B/ RECORD NOT FOUND
        LDU     #ERR:READERROR
        BRA     FDISSUECMD3            B/ CRC ERROR (OR WHO KNOWS WHAT)
        PAGE
FDREAD  JSR     SETRETRYCOUNT
READERROR1
        BITA    #%00010000             WAS THIS A RECORD NOT FOUND (SEEK ERR)?
        BEQ     FDSEEK                 B/ NO, TRY RE-READING IT
        BSR     FDRESTORE
        PAGE
*
*       SEEK -- See if the head must be moved with a seek operation;
*       if it must, the seek is done without verification, as a seek
*       failure will be picked up by a subsequent read/write as
*       "record not found" status, for which the remedy will be
*       a restore operation.  The restore operation IS verified; if
*       it fails, a "seek error" is registered, and the restore is
*       retried, up to the seek-retry count.
*
FDSEEK  ; See if Seek is needed
        LDA     FDCYL,X                FIND OUT WHERE TO PUT THE HEADS
        STA     SSBWDDATA              This will get us to the right track
*
*       I am not doing seek with verify because I assert that the drive
*       is reliable (assumption). If the drive is reliable, then it is
*       pointless to seek with verify, considering the read and write
*       verify automatically. If the drive is not reliable, then (get
*       one that is) the read and write will error and recover correctly.
*       Furthermore, if we do end up on the wrong track, both the seek
*       with verify and the read/write take 5 revs to complain about the
*       wrong track, so again assume it's right and let the read/write
*       tell us otherwise.
*
        LDA     #%00011001             LOAD UP THE SEEK COMMAND
        BSR     FDISSUECMD             Tell 1791 what to do
        BCS     FDREAD5                B/ SOME KIND OF ERROR, PASS IT ON
        PAGE
        LDA     FDSECTOR,X             Get the desired sector number
        INCA                           Add IBM offsets
        STA     SSBWDSECTOR            Tell 1791 what sector to search for
        BSR     SETSSBIOBUFADDRESS
*
*       Sector number register is set, set the side select for
*       the 1791 read command, then read a sector
*
        LDA     #%10000010             PICK UP A READ COMMAND
        BSR     FDISSUECMD             go tell the disk what to do
        LDU     #ERR:READTIMEDOUT      ASSUME A TIMEOUT HAPPENED
        BCS     FDREAD5                B/ ERROR (DON'T BOTHER WITH RETRY)
        ANDA    #%11011111             Ignore delete data mark status
        BNE     FDREADERROR            B/ error status, try to recover
*
*       We read the sector, now move the bytes
*
        BSR     SETSSBIOBUFADDRESS
        LDY     SECTORBASE,X           Point to write buffer
        LDA     #128/2                 PICK UP # OF LOOP ITERATIONS
*
*       Read the on-board I/O buffer
*
FDREAD4 LDU     SSBIOBUFFER            Get two bytes
        STU     ,Y++                   Store the two bytes
        DECA                           Done?
        BNE     FDREAD4                B/ no
        CLRA                           (CLEAR CARRY)
SETSSBIOBUFADDRESS ; CHEAP TRICK HERE THAT HAS NOTHING TO DO WITH FDREAD
        LDD     #$FFFF                 Init the floppy buffer pointer
        STD     SSBIOBUFADRHI
FDREAD5 RTS
        SETDPR  0
        PAGE    LOADER
        IF      SDOSLOADER
        IF      *<<$FE00
        ORG     $FE00
        FIN
*
*       LOADER PROGRAM FOR THE REMOTE COMPUTER
*       READS SDOS LOAD RECORD FORMATS
*
LOADINIT
        LDY     #25000
LDI1    LEAY    -1,Y
        BNE     LDI1
        LDD     #$0316
        STA     CONSOLEPORT
        STA     LOADPORT
        STB     CONSOLEPORT
        STB     LOADPORT
        BSR     LDBUFINIT
LDI2    LDA     LOADPORT
        RORA
        BCC     LDI3
        LDA     LOADPORT+1
        STA     CONSOLEPORT+1
LDI3    LDA     CONSOLEPORT
        RORA
        BCC     LDI2
        LDA     CONSOLEPORT+1
        ANDA    #$7F
        CMPA    #'@-'@
        BEQ     LDI4
        STA     LOADPORT+1
        BRA     LDI2
LDI4    LDB     LOADPORT
        BITB    #$02
        BEQ     LDI4
        LDA     #DC1
        STA     LOADPORT+1
        RTS
*
LDOUT   LDB     CONSOLEPORT
        BITB    #$02
        BEQ     LDOUT
        STA     CONSOLEPORT+1
        RTS
*
LDBUFINIT
        LDX     #$EF02
        STX     -2,X
LDBUFI1 LDA     ,X
        BSR     LDOUT
        CLR     ,X+
        CMPX    #$F000
        BNE     LDBUFI1
        RTS
*
OUTNUM  PSHS    D,X
        PSHS    D
        LDA     #'                   ;
        BSR     OUT1
        PULS    D
        BSR     OUT4
        PULS    D,X,PC
*
OUT4    PSHS    B
        BSR     OUT2
        PULS    A
OUT2    PSHS    A
        LSRA
        LSRA
        LSRA
        LSRA
        BSR     OUTD
        PULS    A
        ANDA    #$0F
OUTD    ADDA    #'0
        CMPA    #'9
        BLS     OUT1
        ADDA    #$07
OUT1    LDX     $EF00
        STA     ,X+
        STX     $EF00
        RTS
*
OUTTYPE PSHS    A
        PSHS    A
        LDA     #CR
        BSR     OUT1
        LDA     #LF
        BSR     OUT1
        LDA     #'T
        BSR     OUT1
        PULS    A
        BSR     OUTD
        PULS    A,PC
*
LOADER  BSR     LOADINIT
        BSR     GETONE
        BSR     OUTTYPE
        CMPA    #2              FIRST LOAD RECORD TYPE 2 ONLY
        BNE     L0              B/ IT ISN'T
        BSR     GETTWO          GET START ADDRESS
        BSR     OUTNUM
        PSHS    D
        BSR     GETTWO          GET CHECKSUM
        BSR     OUTNUM
        COMA
        COMB
        CMPD    0,S
        BEQ     LOADNXT         B/ START RECORD ERROR
        SWI                     START ADDRESS CHECKSUM
L0      SWI                     NOT AN SDOS 6809 LOADABLE FILE
*
*       LOAD THE RECORD, THEN GO BACK FOR MORE
*
LD2     BSR     LD2SUB          LOAD THE RECORD
LOADNXT BSR     GETONE          GET NEXT RECORD TYPE
        BSR     OUTTYPE
        CMPA    #3              LOAD AND GO?
        BEQ     LD3             B/ YES
        CMPA    #2              LOAD?
        BEQ     LD2             B/ YES
        CMPA    #0              SKIP?
        BEQ     LD0             B/ YES
        SWI                     NO, NOT A LOAD RECORD
*
*       LOAD AND GO
*       LOAD THE RECORD, SET REGISTERS, AND ENTER IDB RESET
*
*LD3     BSR     LD2SUB          LOAD THE RECORD
*        ORCC    #$FF            TURN OFF INTS
*        PSHS    CC,D,DP,X,Y,U   MAKE CONTEXT BLOCK
*        JMP     $F80A           FAKE AN NMI
*
LD3     BSR     LD2SUB
        LDD     0,S
        BSR     OUTNUM
        BRA     LDBUFINIT
*
LD2SUB  BSR     GETTWO          GET THE ADDRESS
        BSR     OUTNUM
        TFR     D,Y
        BSR     GETTWO          GET THE COUNT
        BSR     OUTNUM
        TFR     D,X
        LEAX    1,X
SUB1    LEAX    -1,X
        BEQ     SUB4
        BSR     GETONE          GET A DATA BYTE
        CMPY    #$F000
        BHS     SUB3            SKIP REMAINING RECORD
        STA     ,Y+
        BRA     SUB1
SUB2    BSR     GETONE
SUB3    LEAX    -1,X
        BNE     SUB2
SUB4    RTS
*
*       SKIP RECORD
*
LD0     BSR     GETTWO          GET THE COUNT
        BSR     OUTNUM
        TFR     D,X
        LEAX    1,X
LD01    LEAX    -1,X
        BEQ     LOADNXT
        BSR     GETONE          GET A FILL BYTE
        BRA     LD01
*
*       GETTWO
*       RETURN FIRST BYTE IN A, SECOND BYTE IN B
*
GETTWO  BSR     GETONE
        PSHS    D
        BSR     GETONE
        STA     1,S
        PULS    D,PC
*
GETONE  LDA     LOADPORT
        RORA
        BCC     GETONE
        LDA     LOADPORT+1
        RTS
        FIN     SDOSLOADER
        PAGE    LOADER
        IF      *<<$FF00
        ORG     $FF00                  RESET CODE MUST BE ABOVE $FF00
        FIN
*
NMI     LDA     RUNNINGENCRYPTED
        BNE     NMIRTI
        JMP     NMIJMP
NMIRTI  RTI
*
SELECTBANK
        STA     $FFE0
        PULS    U
        CMPS    #STACKE
        BEQ     ERASEMEM
        JMP     ,U
*
RESET1  LDS     #STACKE                USE IDB STACK
        LDA     RUNNINGENCRYPTED
        BEQ     DONTZEROMEMORY         B/ NOT RUNNING ENCRYPTED
        LDA     #8-1                   NUMBER OF USER SPACES
ERASEBANK
        JSR     SELECTBANK             TURN ON USER SPACE (A)
ERASEMEM
        LDX     #$BFFF                 ZERO OUT USER MEMORY
ERASELOOP
        CLR     0,X                    MAKE IT GO AWAY
        DEX
        BNE     ERASELOOP
        DECA                           PRESERVED BY SELECT BANK
        BPL     ERASEBANK              ASSERT NUMBER OF BANKS<128
DONTZEROMEMORY
        CLR     RUNNINGENCRYPTED       MARK 'NOT RUNNING ENCRYPTED'
*
*       SET UP SYSTEM SPACE (MAP 0) WITH 15 PAGES OF MEMORY AND THE
*       I/O PAGE. NOTE THAT THE PAGES ARE ALLOCATED BACKWARDS. THIS
*       DOESN'T HURT A THING AND MAKES THIS ROUTINE TINY, THEREBY
*       CONSERVING MY PRECIOUS ROM SPACE.
*
        LDA     #14                    SET UP MAP 0 WITH 15 RAM PAGES
        LDX     #$FFF0
        CLR     -16,X                  SELECT MAP 0
RESET2  STA     ,X+                    STORE DOWN PHYSICAL PAGE NUMBER
        DECA                           DONE MAPPING THE SYSTEM SPACE?
        BPL     RESET2                 B/ NO, ALLOCATE ANOTHER PAGE
        STA     ,X
*
*       Initialize the PIA for the floppies
*
        LDD     #\$0000                Reset the PIA
        STD     SSBPIACRA              This gets CRA and CRB
*       LDD     #\$00FF                A side is input, B side is output
        CLRB
        STD     SSBPIAORA              This gets DDRA and DDRB
        LDD     #\$0404
        STD     SSBPIACRA
*
*       INITIALIZE THE RAM VECTORS
*
        LDX     #JMPLST
        LDY     #SWI3JMP
        LDB     #JMPLSTEND-JMPLST
RESET3  LDA     ,X+
        STA     ,Y+
        DECB
        BNE     RESET3
        IF      SDOSLOADER
        JMP     LOADER
        ELSE
        JMP     DEBUG                  START THE DEBUGGER
        FIN
*
JMPLST
        JMP     NMIH                   SWI3JMP
        JMP     NMIH                   SWI2JMP
        JMP     FIRQENTRY              FIRQJMP
        JMP     NMIH                   IRQJMP
        IF      USESWIFORBREAKPOINT
        JMP     BREAKPOINT             SWIJMP
        ELSE
        JMP     NMIH                   SWIJMP
        FIN
        JMP     NMIH                   NMIJMP
JMPLSTEND
        IF      *>>$FFD5
        ? ROM CODE OVERWRITES SERIAL NUMBER ?
        FIN
        ORG     $FFD5
*
*       SERIALNUMBER MUST NOT BE LOCATED ON TOP OF THE MAP (FFE0..FFFF)
*       JUST BELOW THE MAP IS A GOOD PLACE FOR IT WHERE IT WILL
*       NEVER HAVE TO MOVE
*
RESET   JMP     RESET1
        FDB     $5500,0,0,0            8-BYTE SERIAL NUMBER
*
*       ASSIGN PAGE NUMBER IN (B) TO MAP NUMBER (A) SLOT (X)
*       RESTORES MAP TO SYSTEM SPACE WHEN FINISHED
*       CALLED FROM MT
*       THIS IS GOOD FILLER BETWEEN THE SERIAL NUMBER AND THE VECTORS
*
ASSIGNPAGETOMAP1
        STA     $FFE0                  BANK SELECT
        STB     ,X                     ASSIGN THE PAGE
        CLR     $FFE0                  SELECT SYSTEM SPACE
        CLI
        RTS
        PAGE    6809 Vectors
        IF      *>>$FFEC
        ? ROM CODE OVERWRITES RESET VECTORS ?
        FIN
        ORG     $FFEC
ASSIGNPAGETOMAP
        BRA     ASSIGNPAGETOMAP1
READSECTOR
        JMP     [READSECTORADDRESS]
        FDB     SWI3JMP
        FDB     SWI2JMP
        FDB     FIRQJMP
        FDB     IRQJMP
        FDB     SWIJMP
        FDB     NMI
        FDB     RESET
*
        ORG     GETC
        JMP     GETCHAR
        JMP     PCHAR
        JMP     PRINTASCIIZ
        JMP     OPENLOAD
        JMP     READLOAD
        JMP     CLOSELOAD
        JMP     INITIALIZE
*
        END     DEBUG
