;**************************************************************************
;***                                                                    ***
;*** Micro Lab Monitor                                                  ***
;*** (C) 1993 G. MacDonald                                              ***
;***                                                                    ***
;***    Name:           System Monitor                                  ***
;***    Version:        1.10d                                           ***
;***    Author:         Geoff MacDonald                                 ***
;***    Date:           14/01/1993-15/01/1993                           ***
;***    Last Update:    12/11/1993                                      ***
;***                                                                    ***
;**************************************************************************

                ;The machine code monitor provides the user of the
                ;Micro-Lab with all the facilities required to enter,
                ;debug and run machine code programs.
                ;
                ;The monitor comprises four parts:
                ;  1. Zero page definition
                ;  2. Demonstration programs
                ;  3. Basic input/output system functions
                ;       Reset procedure
                ;       Interrupts
                ;       Input from keyboard
                ;       Character and hex output to LCD
                ;       ASCII to binary conversion
                ;  4. Operating system functions
                ;       Monitor commands
                ;       Machine code monitor
                ;
                ;All monitor routines leave the registers intact, except
                ;when a routine returns a value or otherwise specified.

                ;UPDATES:
                ;V1.10d
                ;       1. Printer output routines implemented.
                ;       2. Extra monitor commands added:
                ;             Hex dump of memory       (^9 - H)
                ;             Disassemble program      (^8 - D)
                ;             Branch offset calculator (^7 - O)
                ;             Memory block transfer    (^6 - X)
                ;       3. Common LCD/Printer output routine implemented.
                ;       4. Power up RAM test


;**************************************************************************
;*** ZERO PAGE DEFINITION                                               ***
;**************************************************************************

                DATASEG $0000

;-------------------------------------------------------------------------;
; Vectors to BIOS functions                                               ;
;-------------------------------------------------------------------------;
INTVEC:         DFB     ?,?,?
NMIVEC:         DFB     ?,?,?
OPCHAR:         DFB     ?,?,?
CURSOR:         DFB     ?,?,?
CLEAR:          DFB     ?,?,?
NEWLINE:        DFB     ?,?,?
POSCHAR:        DFB     ?,?,?
SOUND:          DFB     ?,?,?
DELAY:          DFB     ?,?,?
KBWAIT:         DFB     ?,?,?
KBLAST:         DFB     ?,?,?
KBCLR:          DFB     ?,?,?
HEXOUT:         DFB     ?,?,?
HEXIN:          DFB     ?,?,?
STRING:         DFB     ?,?,?
PCHAR:          DFB     ?,?,?
PINIT:          DFB     ?,?,?
LCDCHAR:        DFB     ?,?,?

;-------------------------------------------------------------------------;
; Keyboard buffer                                                         ;
;-------------------------------------------------------------------------;
                DATASEG $0048
KBUFF:          DFB     ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?
KBHEAD:         DFB     ?
KBTAIL:         DFB     ?
KBSIZE:         DFB     ?

;-------------------------------------------------------------------------;
; Output/printing device flags, cursor position and cursor status         ;
;-------------------------------------------------------------------------;
CURX:           DFB     ?               ;LCD cursor X position
CURY:           DFB     ?               ;LCD cursor Y position
CURSTAT:        DFB     ?               ;LCD cursor on/off
SCROLL:         DFB     ?               ;LCD scroll enable
OPREG:          DFB     ?               ;Output register:
                                        ;   b0 = LCD on
                                        ;   b1 = Printer on
                                        ;   b2 = UART on
PRDEV:          DFB     ?               ;Printing device:
                                        ;   b1 = Parallel
                                        ;   b2 = Serial
CONSOLE:        DFB     ?               ;Input/Output console:
                                        ;   b0 = LCD
                                        ;   b2 = Serial (terminal)

;-------------------------------------------------------------------------;
; User program register storage                                           ;
;-------------------------------------------------------------------------;
PCLO:           DFB     ?
PCHI:           DFB     ?
SP:             DFB     ?
PSW:            DFB     ?
ACC:            DFB     ?
IX:             DFB     ?
IY:             DFB     ?

;-------------------------------------------------------------------------;
; Single step and breakpoint storage                                      ;
;-------------------------------------------------------------------------;
SINGLE:         DFB     ?
BPTAB:          DFB     ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?
BPOPCODE:       DFB     ?,?,?,?,?,?,?,?

;-------------------------------------------------------------------------;
; Scratchpad area                                                         ;
;-------------------------------------------------------------------------;
HARDRES:        DFB     ?,?,?
GP1:            DFB     ?
GP2:            DFB     ?
GP3:            DFB     ?
PAR_L:          DFB     ?
PAR_H:          DFB     ?
CMDKEY:         DFB     ?
CMDPAR:         DFB     ?,?,?,?
CMD:            DFB     ?

                ENDSEG

;-------------------------------------------------------------------------;
; Peripheral addresses                                                    ;
;-------------------------------------------------------------------------;
LED             =       $8000
DIPSW           =       $8010
AIN             =       $8020
AOUT            =       $8030
VIA             =       $8040
LCDCMD          =       $8050
LCDDTA          =       $8051
KBDTA           =       $8060
KBCMD           =       $8061
STLATCH         =       $8070

;-------------------------------------------------------------------------;
; Hard reset status constants                                             ;
;-------------------------------------------------------------------------;
HR1             =       $47
HR2             =       $4D
HR3             =       $44

;-------------------------------------------------------------------------;
; Keyboard function key definitions                                       ;
;-------------------------------------------------------------------------;
NUMCMDS         =       11
KEYENT          =       $0D
KEYSTOP         =       $03
KEYESC          =       $1B
KEYGO           =       'G'
KEYMOD          =       'M'
KEYSTEP         =       'S'
KEYREG          =       'R'
KEYBRK          =       'B'
KEYDEMO         =       '#'
KEYDUMP         =       'H'
KEYPDIS         =       'D'
KEYOFS          =       'O'
KEYXFR          =       'X'
KEYPDEV         =       'P'
KEYCON          =       'T'
KEYUP           =       $0B
KEYDOWN         =       $0A
KEYDEL          =       $7F


;**************************************************************************
;*** DEMONSTRATION PROGRAMS                                             ***
;**************************************************************************

                ORG     $E000
                INCLUDE TUNE1.ASM
                @=$E080
                INCLUDE TUNE2.ASM
                @=$E100
                INCLUDE DEMO0.ASM
                INCLUDE DEMO1.ASM
                INCLUDE DEMO2.ASM
                INCLUDE DEMO3.ASM
                INCLUDE DEMO4.ASM
                INCLUDE DEMO5.ASM
                INCLUDE DEMO6.ASM
                INCLUDE DEMO7.ASM
                INCLUDE DEMO8.ASM
                INCLUDE DEMO9.ASM
                INCLUDE DEMOA.ASM


;**************************************************************************
;*** BIOS FUNCTIONS                                                     ***
;**************************************************************************

                ;Routines with a B_ prefix are RAM vectored BIOS function
                ;calls.  The vectors are initialised when the system is
                ;reset.  The user may modify these RAM vectors to call
                ;his/her own routines.

;-------------------------------------------------------------------------;
; Reset routine                                                           ;
;-------------------------------------------------------------------------;
RESET:          LDX     #$FF            ;Initialise stack pointer
                TXS
                CLD
                LDA     HARDRES         ;Do a hard reset?
                CMP     #HR1
                BNE     HARDRESET
                LDA     HARDRES+1
                CMP     #HR2
                BNE     HARDRESET
                LDA     HARDRES+2
                CMP     #HR3
                BEQ     RESET2
HARDRESET:      LDA     #$FE
                STA     GP1
                LDA     #$00            ;Yes - Set entire RAM to $00
                STA     $00
                STA     $01
                LDY     #$02
CLRRAM1:        STA     ($00),Y
                INY
                BNE     CLRRAM1
                INC     $01
                LDX     $01
                LDA     GP1
                STA     LED
                SEC
CLRRAM2:        ROL     A
                BCC     CLRRAM2
                STA     GP1
                LDA     #$00
                CPX     #$80
                BNE     CLRRAM1
                STA     $00
                STA     $01
RESET2:         JSR     BIOSINIT        ;Initialise BIOS
                JSR     MEMTEST         ;Test memory
                JSR     OSINIT          ;Initialise OS
                LDX     #>MONMSG        ;Display monitor message
                LDY     #<MONMSG
                JSR     STRING
                LDA     #20             ;Wait 1/2 second
                JSR     DELAY
                JSR     NEWLINE
                JMP     MONSTART        ;Execute monitor


;-------------------------------------------------------------------------;
; Keyboard/65C22 interrupt routine:                                       ;
;    Unless the RAM vector has been modified, this routine is             ;
;    called whenever a key is pressed or 65C22 generates an interrupt.    ;
;    If a key has been pressed, the scan code of the key is read and      ;
;    converted into an ASCII character which is then stored in the        ;
;    keyboard buffer.  If the buffer is full, the key is ignored.         ;
;    If the key is Shift-ESC, then a BRK instruction is simulated.        ;
;-------------------------------------------------------------------------;
B_NMI:          PHA                     ;Save registers
                TXA
                PHA
                CLD
                LDA     KBCMD           ;Get FIFO status
                AND     #$07            ;Get number of keys in FIFO
                BEQ     INT1            ;None in FIFO, so terminate
                LDA     #$50            ;Read FIFO data
                STA     KBDTA
                LDA     KBDTA
                AND     #$7F            ;Ignore CNTL input
                TAX
                LDA     KBSIZE          ;Keyboard buffer full?
                CMP     #$0F
                BEQ     INT1
                LDA     KBMAP,X         ;Convert to ASCII
                BEQ     INT1
                CMP     #KEYSTOP        ;Shift-ESC pressed?
                BEQ     INT2            ;Yes - jump to INT routine
                LDX     KBTAIL          ;Store key in buffer
                STA     KBUFF,X
                INC     KBSIZE          ;Change buffer pointers
                INX
                TXA
                AND     #$0F
                STA     KBTAIL
INT1:           PLA
                TAX
                PLA
                CLI
                RTI
INT2:           PLA                     ;Shift-ESC pressed...
                TAX
                PLA
                JMP     INTVEC          ;Jump to INTVEC routine


;-------------------------------------------------------------------------;
;    This routine is called whenever a BRK instruction is executed        ;
;    It saves the user registers in RAM, instructs the monitor to display ;
;    these registers and then hands control to the monitor.               ;
;-------------------------------------------------------------------------;
B_INT:          STA     ACC             ;Save user registers
                STX     IX
                STY     IY
                PLA                     ;Save PSW
                STA     PSW
                CLD
                PLA                     ;Save address
                STA     PCLO
                PLA
                STA     PCHI
                TSX
                TXA
                STA     SP
                TAX
                LDA     SINGLE          ;Turn single stepping off
                BEQ     BRK3
                STA     STLATCH
BRK3:           LDX     #$00            ;Restore op-codes destroyed by BPs
                LDY     #$00
BRK1:           LDA     BPTAB,X
                ORA     BPTAB+1,X
                BEQ     BRK2
                LDA     BPOPCODE,Y
                STA     (BPTAB,X)
BRK2:           INX
                INX
                INY
                CPY     #$08
                BNE     BRK1
                CLI
                JMP     SHOWREG         ;Show regs. and restart monitor


;-------------------------------------------------------------------------;
; Simple memory test.  Writes $55 and $AA to each RAM location and reads  ;
; the result back.  Displays the addresses of any locations which fail.   ;
;-------------------------------------------------------------------------;
MEMTEST:        LDX     #>MSG29         ;Display memory test message
                LDY     #<MSG29
                JSR     STRING
                LDA     #$00            ;Set up first test location ($0100)
                STA     GP1
                LDA     #$01
                STA     GP2
                LDY     #$00
                STY     GP3
MEMTEST3:       LDA     (GP1),Y         ;Read contents of current location
                TAX                     ;and store in IX
                LDA     #$55
                STA     (GP1),Y         ;Store $55 in current location
                CMP     (GP1),Y         ;Read it back.
                BNE     MEMTEST7        ;Error - display address
MEMTEST1:       LDA     #$AA
                STA     (GP1),Y         ;Store $AA in current location
                CMP     (GP1),Y         ;Read it back.
                BEQ     MEMTEST2
MEMTEST7:       LDA     GP3
                BNE     MEMTEST8
                JSR     NEWLINE
MEMTEST8:       LDA     GP2             ;Error - display address
                JSR     HEXOUT
                TYA
                JSR     HEXOUT
                LDA     #$20
                JSR     OPCHAR
                JSR     OPCHAR
                JSR     OPCHAR
                JSR     OPCHAR
                LDA     #$01            ;Flag error
                STA     GP3
MEMTEST2:       TXA                     ;Restore contents
                STA     (GP1),Y
                INY                     ;Get next location
                BNE     MEMTEST3
                LDA     GP2
                LSR     A
                LSR     A
                LSR     A
                LSR     A
                TAX
                LDA     LEDBAR,X
                STA     LED
                INC     GP2
                BPL     MEMTEST3
                JSR     NEWLINE
                LDA     GP3             ;Display result
                BNE     MEMTEST4
                LDX     #>MSG30         ;Passed
                LDY     #<MSG30
                JSR     STRING
                LDA     #20             ;Wait 1/2 second
                JSR     DELAY
                JMP     MEMTEST5
MEMTEST4:       LDX     #>MSG31         ;Failed...
                LDY     #<MSG31
                JSR     STRING
MEMTEST6:       JSR     KBWAIT          ;Wait for [ENTER] key
                CMP     #$0D
                BNE     MEMTEST6
MEMTEST5:       JSR     NEWLINE
                LDA     #$FF
                STA     LED
                RTS

;-------------------------------------------------------------------------;
; Display a character on the LCD:                                         ;
;   Acc = ASCII code of character to display                              ;
;   The display is scrolled up when required                              ;
;   The routine also performs the following:                              ;
;       $08 = Backspace                                                   ;
;       $0A = Line feed                                                   ;
;       $0C = Clear display                                               ;
;       $0D = Carriage return                                             ;
;       $7F = Delete                                                      ;
;-------------------------------------------------------------------------;
B_LCDCHAR:      STA     GP3
                PHA                     ;Save registers
                TXA
                PHA
                TYA
                PHA
                LDA     GP3

                CMP     #$08            ;Backspace or Delete?
                BEQ     LCDCHARB
                CMP     #$7F
                BNE     LCDCHAR4
LCDCHARB:       PHA
                LDA     CURX            ;Cursor at start of line
                AND     #$3F
                BEQ     LCDCHARA         ;Yes - terminate
                DEC     CURX            ;No - decrement cursor position
                LDX     CURX
                LDY     CURY
                LDA     CURSTAT
                JSR     CURSOR
                PLA                     ;Delete?
                PHA
                CMP     #$7F
                BNE     LCDCHARA
                LDA     #$20            ;Yes - Display a space
                JSR     LCDWRITE
                LDX     CURX
                LDY     CURY
                LDA     CURSTAT
                JSR     CURSOR
LCDCHARA:       PLA
                JMP     LCDCHAR3

LCDCHAR4:       CMP     #$0A            ;Line feed?
                BNE     LCDCHAR5
                LDY     CURY            ;Cursor on bottom line?
                CPY     #$00
                BEQ     LCDCHAR9
                JSR     LCDSCR          ;Yes - scroll screen up
LCDCHAR9:       LDY     #$01            ;Move cursor to bottom line
                LDX     CURX
                LDA     CURSTAT
                JSR     CURSOR
                JMP     LCDCHAR3

LCDCHAR5:       CMP     #$0C            ;Clear screen?
                BNE     LCDCHAR6
                JSR     CLEAR
                JMP     LCDCHAR3

LCDCHAR6:       CMP     #$0D            ;Carriage return?
                BNE     LCDCHAR8
                LDA     CURX            ;Position cursor at start of line
                AND     #$40
                STA     CURX
                TAX
                LDY     CURY
                LDA     CURSTAT
                JSR     CURSOR
                JMP     LCDCHAR3

LCDCHAR8:       JSR     LCDWRITE        ;Normal character
                INC     CURX            ;Increment cursor position
                LDA     CURX            ;Past end of bottom line?
                CMP     #$10
                BNE     LCDCHAR2
LCDCHAR1:       LDX     #$00            ;Yes - move to start of bottom line
                LDY     #$01
                LDA     CURSTAT
                JSR     CURSOR
                JMP     LCDCHAR3
LCDCHAR2:       CMP     #$50            ;Past end of bottom line?
                BNE     LCDCHAR3
                JSR     LCDSCR          ;Scroll LCD up one line
                JMP     LCDCHAR1        ;Move to start of bottom line
LCDCHAR3:       PLA
                TAY
                PLA
                TAX
                PLA
                RTS


;-------------------------------------------------------------------------;
; Position and display/hide display cursor                                ;
;    Acc b0 = 0:hide cursor, 1:show cursor                                ;
;    IX = New X position (0-15)                                           ;
;    IY = New Y position (0-1)                                            ;
;-------------------------------------------------------------------------;
B_CURSOR:       PHA
                AND     #$01            ;Hide/Display cursor
                STA     CURSTAT
                STX     CURX
                STY     CURY
                ORA     #$0C
                JSR     LCDINST
                TXA                     ;Calculate LCD RAM address
                AND     #$0F
                STA     GP3
                TYA
                AND     #$01
                ASL     A
                ASL     A
                ASL     A
                ASL     A
                ASL     A
                ASL     A
                CLC
                ADC     GP3
                ORA     #$80            ;Convert into instruction
                JSR     LCDINST         ;Position cursor
                PLA
                RTS


;-------------------------------------------------------------------------;
; Clear display                                                           ;
;-------------------------------------------------------------------------;
B_CLEAR:        PHA
                TXA
                PHA
                TYA
                PHA
                LDX     #$00            ;Cursor home
                LDY     #$00
                LDA     CURSTAT
                JSR     CURSOR
                LDA     #$01            ;LCD clear command
                JSR     LCDINST
                PLA
                TAY
                PLA
                TAX
                PLA
                RTS


;-------------------------------------------------------------------------;
; Move to start of next line                                              ;
;-------------------------------------------------------------------------;
B_NEWLINE:      PHA
                LDA     #$0A            ;Send LF
                JSR     OPCHAR
                LDA     #$0D            ;Send CR
                JSR     OPCHAR
                PLA
                RTS


;-------------------------------------------------------------------------;
; Display the ASCII character in Acc at position IX,IY                    ;
;-------------------------------------------------------------------------;
B_POSCHAR:      STA     GP1             ;Save character
                TXA                     ;Save registers
                PHA
                TYA
                PHA
                LDA     CURSTAT         ;Save cursor state
                PHA
                LDA     CURX            ;Save cursor X position
                PHA
                LDA     CURY            ;Save cursor Y position
                PHA
                LDA     #0              ;Hide cursor
                JSR     CURSOR          ;Position cursor
                LDA     GP1             ;Restore character
                JSR     LCDWRITE        ;Put character on screen
                PLA                     ;Restore cursor state and position
                TAY
                PLA
                TAX
                PLA
                JSR     CURSOR
                PLA                     ;Restore registers
                TAY
                PLA
                TAX
                LDA     GP1
                RTS


;-------------------------------------------------------------------------;
; 65C22 based sound output                                                ;
;   Acc = 0: Initialise 65C22 for sound output                            ;
;   Acc = 1: Produce sound                                                ;
;       IX = High byte of pitch                                           ;
;       IY = Low byte of pitch                                            ;
;-------------------------------------------------------------------------;
B_SOUND:        CMP     #$00            ;Initialise 65C22?
                BEQ     SOUND1
                PHA
                LDA     #$40            ;Yes - Disable T1 interrupt
                STA     VIA+14
                LDA     VIA+2           ;Set PB7 as input (no sound)
                ORA     #$80
                STA     VIA+2
                LDA     #$C0            ;T1 free run, inverting PB7
                STA     VIA+11
                PLA
                RTS
SOUND1:         CPX     #$00            ;No - sound off (IX=IY=0)?
                BNE     SOUND2
                CPY     #$00
                BNE     SOUND2
                PHA
                LDA     VIA+2           ;Turn sound off (PB7 = input)
                AND     #$7F
                STA     VIA+2
                LDA     #$00
                STA     VIA+11
                LDA     #$80
                STA     VIA+14
                PLA
                RTS
SOUND2:         PHA                     ;Generate output...
                STX     VIA+7           ;Set up frequency
                STY     VIA+6
                STX     VIA+5           ;Enable T1 time out facility
                PLA
                RTS


;-------------------------------------------------------------------------;
; Delay for specified time                                                ;
;   Acc = time in 1/100 seconds                                           ;
; NOTE: this routine assumes a 1MHz clock (IE 1uS processor cycle time)   ;
;-------------------------------------------------------------------------;
B_DELAY:        STA     GP1             ;Save delay time
                TXA                     ;Save X register
                PHA
                TYA                     ;Save Y register
                PHA
                LDA     GP1             ;Restore delay time
DELAY1:         LDX     #40             ;Delay for 1/100 second...
DELAY2:         LDY     #61
DELAY3:         DEY
                BNE     DELAY3
                DEX
                BNE     DELAY2
                SEC                     ;...Required number of times
                SBC     #$01
                BNE     DELAY1
                PLA                     ;Restore registers
                TAY
                PLA
                TAX
                LDA     GP1
                RTS


;-------------------------------------------------------------------------;
; Return last key pressed.  If no key is pressed then wait                ;
;   Acc = ASCII code of key pressed                                       ;
;-------------------------------------------------------------------------;
B_KBWAIT:       LDA     KBSIZE          ;Key in buffer?
                BEQ     B_KBWAIT        ;No - wait until there is
                JSR     KBLAST          ;Get ASCII code of last key pressed
                RTS


;-------------------------------------------------------------------------;
; Return last key pressed.  If no key in buffer, then return $00          ;
;   Acc = ASCII code of key pressed                                       ;
;-------------------------------------------------------------------------;
B_KBLAST:       STX     GP1             ;Save X-register
                LDA     KBSIZE          ;Key in buffer?
                BEQ     KBLAST1         ;No - terminate
                LDX     KBHEAD          ;Yes - Get buffer position
                LDA     KBUFF,X         ;Get key value
                PHA                     ;Save it
                INX                     ;Point to next character
                TXA
                AND     #$0F            ;Wrap around, if necessary
                STA     KBHEAD          ;Store it
                DEC     KBSIZE          ;Defcrement buffer size
                PLA                     ;Restore key
KBLAST1:        LDX     GP1             ;Restore X-register
                CMP     #$00
                RTS


;-------------------------------------------------------------------------;
; Empty keyboard buffer                                                   ;
;-------------------------------------------------------------------------;
B_KBCLR:        PHA                     ;Save accumulator
KBCLR1:         JSR     KBLAST          ;Get first key in buffer
                BNE     KBCLR1          ;Repeat until buffer empty
                PLA
                RTS


;-------------------------------------------------------------------------;
; Display number in hexadecimal                                           ;
;   Acc = Number to display                                               ;
;-------------------------------------------------------------------------;
B_HEXOUT:       PHP
                CLD
                PHA                     ;Save number
                PHA
                AND     #$F0            ;Get high nybble of number
                LSR     A               ;Move into low nybble
                LSR     A
                LSR     A
                LSR     A
                CMP     #$0A            ;Number or letter?
                BMI     HEXOUT1
                CLC                     ;Letter - so add 6
                ADC     #$07
HEXOUT1:        CLC                     ;Convert to ASCII
                ADC     #$30
                JSR     OPCHAR          ;Display high nybble
                PLA
                AND     #$0F            ;Get low nybble of number
                CMP     #$0A            ;Number or letter?
                BMI     HEXOUT2
                CLC                     ;Letter - so add 6
                ADC     #$07
HEXOUT2:        CLC                     ;Convert to ASCII
                ADC     #$30
                JSR     OPCHAR          ;Display low nybble
                PLA                     ;Restore accumulator
                PLP
                RTS


;-------------------------------------------------------------------------;
; Convert ASCII hexadecimal number into binary                            ;
;   Acc = (in) address (ZP) of number to convert                          ;
;   IY = (in) Number of bytes to convert                                  ;
;   IX = (out) High byte of result                                        ;
;   IY = (out) Low byte of result                                         ;
;   CF = (out) 0 if conversion OK                                         ;
;-------------------------------------------------------------------------;
B_HEXIN:        PHP
                CLD
                PHA                     ;Save accumulator
                STY     GP3
                LDX     #$00            ;Clear result
                STX     GP1
                STX     GP2
                TAX
HEXIN1:         LDY     #$04            ;Multiply result by 16
HEXIN2:         ASL     GP1
                ROL     GP2
                DEY
                BNE     HEXIN2
                LDA     $00,X           ;Get next character
                SEC                     ;Convert ASCII to binary
                SBC     #$30
                BMI     HEXIN5          ;Invalid character - terminate
                CMP     #$11            ;Letter?
                BMI     HEXIN4
                SEC                     ;Yes - subtract 6
                SBC     #$07
HEXIN4:         CMP     #$10            ;Binary number>15?
                BPL     HEXIN4          ;Yes - terminate
                ORA     GP1             ;Add it to the result
                STA     GP1
                INX                     ;Point to next character
                DEC     GP3
                BNE     HEXIN1          ;Repeat
HEXIN3:         PLA                     ;Restore accumulator
                LDX     GP2             ;Get high byte into IX
                LDY     GP1             ;Get low byte into IY
                PLP
                CLC                     ;Flag conversion OK
                RTS
HEXIN5:         PLA                     ;Invalid character found...
                LDX     GP2             ;Get result of conversion
                LDY     GP1
                PLP
                SEC                     ;Flag error
                RTS



;-------------------------------------------------------------------------;
; Display a NULL terminated string                                        ;
;   IX = High byte of string start address                                ;
;   IY = Low byte of string start address                                 ;
;-------------------------------------------------------------------------;
B_STRING:       PHA                     ;Save registers
                TYA
                PHA
                STY     GP1             ;Store address
                STX     GP2
                LDY     #$00
STRING1:        LDA     (GP1),Y         ;Get character to display
                BEQ     STRING2         ;Character = $00?
                JSR     OPCHAR          ;No - display it
                INY                     ;Point to next character...
                BNE     STRING1         ;...and repeat
STRING2:        PLA                     ;Restore registers
                TAY
                PLA
                RTS


;-------------------------------------------------------------------------;
; Wait until the LCD has completed the last command                       ;
;-------------------------------------------------------------------------;
LCDBUSY:        PHA
LCDBUSY1:       LDA     LCDCMD          ;Read from LCD command register
                BMI     LCDBUSY1        ;Repeat until Busy Flag is low
                PLA
                RTS


;-------------------------------------------------------------------------;
; Send an instruction to the LCD                                          ;
;   Acc = command to send                                                 ;
;-------------------------------------------------------------------------;
LCDINST:        JSR     LCDBUSY         ;Wait until LCD can accept command
                STA     LCDCMD          ;Send command to LCD
                JSR     LCDBUSY         ;Wait until command performed
                RTS


;-------------------------------------------------------------------------;
; Send data to the LCD                                                    ;
;  Acc = data to send                                                     ;
;-------------------------------------------------------------------------;
LCDWRITE:       JSR     LCDBUSY         ;Wait until LCD can accept data
                STA     LCDDTA          ;Send the data to the LCD
                JSR     LCDBUSY         ;Wait until data received
                RTS


;-------------------------------------------------------------------------;
; Read data from the LCD                                                  ;
;   Acc = data returned                                                   ;
;-------------------------------------------------------------------------;
LCDREAD:        JSR     LCDBUSY         ;Wait until LCD can send data
                LDA     LCDDTA          ;Read data from the LCD
                JSR     LCDBUSY         ;Wait until LCD can continue
                RTS


;-------------------------------------------------------------------------;
; Scroll the LCD up one line                                              ;
;-------------------------------------------------------------------------;
LCDSCR:         PHA                     ;Save registers
                TXA
                PHA
                TYA
                PHA
                LDA     SCROLL          ;Scroll enabled?
                BEQ     LCDSCR2
                LDA     #$0D            ;Yes...
                JSR     LCDINST         ;Cursor off
                LDX     #$C0            ;IX=Left char. on bottom line
                LDY     #$80            ;IY=Left char. on top line
LCDSCR1:        TXA                     ;Get character from bottom line
                JSR     LCDINST
                JSR     LCDREAD
                PHA                     ;Save character
                TXA
                JSR     LCDINST
                LDA     #$20            ;Store a space on bottom line
                JSR     LCDWRITE
                TYA                     ;Store it in top line
                JSR     LCDINST
                PLA
                JSR     LCDWRITE
                INX                     ;Increment display pointers
                INY
                CPY     #$90            ;Done whole line?
                BNE     LCDSCR1         ;No - repeat
                LDX     CURX            ;Restore cursor state and position
                LDY     CURY
                LDA     CURSTAT
                JSR     CURSOR
LCDSCR2:        PLA                     ;Restore registers
                TAY
                PLA
                TAX
                PLA
                RTS


;-------------------------------------------------------------------------;
; Initialise the LCD                                                      ;
;-------------------------------------------------------------------------;
LCDINIT:        PHA
                LDA     #$02            ;Delay 20mS
                JSR     DELAY
                LDA     #$30            ;Set interface length to 8 bits
                STA     LCDCMD
                LDA     #$01            ;Delay 10mS
                JSR     DELAY
                LDA     #$30
                STA     LCDCMD
                LDA     #$01            ;Delay 10mS
                JSR     DELAY
                LDA     #$30
                STA     LCDCMD
                LDA     #$01            ;Delay 10mS
                JSR     DELAY
                LDA     #$38            ;2 lines, 5x7 dots, 8 bit interface
                STA     LCDCMD
                LDA     #$08            ;Display off
                JSR     LCDINST
                LDA     #$01            ;Display on
                JSR     LCDINST
                LDA     #$06            ;Cursor auto increments
                JSR     LCDINST
                LDA     #$0D            ;Cursor blinking
                JSR     LCDINST
                LDX     #$00            ;Hide cursor and move home
                LDY     #$00
                LDA     #$00
                JSR     CURSOR
                LDA     #$01            ;Clear screen
                JSR     LCDINST
                LDA     #$01            ;Enable scrolling
                STA     SCROLL
                PLA
                RTS


;-------------------------------------------------------------------------;
; Initialise the keyboard                                                 ;
;-------------------------------------------------------------------------;
KBINIT:         LDA     #$01            ;Encoded scan, 2-key lockout
                STA     KBCMD
                LDA     #$2A            ;Clock divided by 10 (~5mS scan)
                STA     KBCMD
                LDA     #$0B3           ;Clear keyboard FIFO stack
                STA     KBCMD
                RTS


;-------------------------------------------------------------------------;
; Initialise the 6522 for printer output                                  ;
;-------------------------------------------------------------------------;
B_PINIT:        PHA
                LDA     #$FF            ;Set port A for all outputs
                STA     VIA+$03
                LDA     #$00            ;And all = 0V.
                STA     VIA+$01
                LDA     #$0E            ;Set printer strobe high
                STA     VIA+$0C
                PLA
                RTS


;-------------------------------------------------------------------------;
; Send the character in the accumulator to the printer                    ;
;   Acc = Character to send                                               ;
;-------------------------------------------------------------------------;
B_PCHAR:        PHA
                STA     VIA+$01         ;Place acc. on printer data lines
                TXA
                PHA
                TYA
                PHA
                LDX     #$00
PCHAR6:         DEX
                BNE     PCHAR6
                LDA     #$0C            ;Set strobe low
                STA     VIA+$0C
                LDX     #$00
PCHAR5:         DEX
                BNE     PCHAR5
                LDA     #$0E            ;Set strobe high
                STA     VIA+$0C
                LDA     #$08
                LDX     #$00
                LDY     #$00
PCHAR1:         PHA
                LDA     VIA+$0D         ;Read acknowledge input...
                AND     #$02
                BNE     PCHAR2          ;...Until character acknowledged
                PLA
                DEX
                BNE     PCHAR1          ;...Or until printer timeout
                DEY
                BNE     PCHAR1
                SEC
                SBC     #$01
                BNE     PCHAR1
                LDA     OPREG
                PHA
                LDA     CONSOLE
                STA     OPREG
                LDX     #>MSG20         ;Output error message to LCD/UART
                LDY     #<MSG20
                JSR     STRING
                PLA
                STA     OPREG
PCHAR3:         JSR     KBWAIT          ;Wait for user key press
                CMP     #KEYENT
                BNE     PCHAR4          ;[ENTER] pressed, so try again
                JSR     CLEAR
                PLA
                TAY
                PLA
                TAX
                PLA
                JMP     B_PCHAR
PCHAR4:         CMP     #KEYESC
                BNE     PCHAR3
                LDX     #$FF            ;[ESC] pressed, so restart monitor
                TXS
                JMP     MONSTART
PCHAR2:         PLA
                PLA
                TAY
                PLA
                TAX
                PLA
                RTS


;-------------------------------------------------------------------------;
; Output Character in Accumulator to LCD/Printer/UART                     ;
;    Output devices are selected by writing to OPREG:                     ;
;       b0 = 1 for output to LCD                                          ;
;       b1 = 1 for output to Printer                                      ;
;       b2 = 1 for output to UART                                         ;
;-------------------------------------------------------------------------;
B_OPCHAR:       PHA
                LDA     OPREG
                AND     #$01
                BEQ     OPCHAR1
                PLA
                JSR     LCDCHAR
                PHA
OPCHAR1:        LDA     OPREG
                AND     #$02
                BEQ     OPCHAR2
                PLA
                JSR     PCHAR
                PHA
OPCHAR2:        PLA
                RTS


;-------------------------------------------------------------------------;
; Initialise BIOS                                                         ;
;-------------------------------------------------------------------------;
BIOSINIT:       SEI                     ;Disable interrupts
                PHA                     ;Save registers
                TXA
                PHA
                LDA     #HR1            ;Clear hard reset status
                STA     HARDRES
                LDA     #HR2
                STA     HARDRES+1
                LDA     #HR3
                STA     HARDRES+2
                LDX     #$00            ;Initialise vector table
BIOSINIT1:      LDA     VECTAB,X
                BEQ     BIOSINIT2
                STA     $00,X
                INX
                LDA     VECTAB,X
                STA     $00,X
                INX
                LDA     VECTAB,X
                STA     $00,X
                INX
                BNE     BIOSINIT1
BIOSINIT2:      LDA     #$FF            ;Switch all LEDs off
                STA     LED
                LDA     #$00            ;Analogue output to 0V
                STA     AOUT
                LDA     #$00            ;Clear keyboard buffer
                STA     KBHEAD
                STA     KBTAIL
                STA     KBSIZE
                STA     SINGLE          ;Single step off
                JSR     LCDINIT         ;Initialise the LCD
                JSR     KBINIT          ;Initialise the keyboard
                LDA     #$01            ;Set output to LCD only
                STA     OPREG
                LDX     #>BIOSMSG       ;Display BIOS installed message
                LDY     #<BIOSMSG
                JSR     STRING
                LDA     #20             ;Wait 200mS
                JSR     DELAY
                PLA
                TAX
                PLA
                CLI                     ;Enable interrupts
                RTS


;**************************************************************************
;*** OPERATING SYSTEM FUNCTIONS                                         ***
;**************************************************************************

                ;Routines having a C_ prefix are user commands.  When
                ;executed, IX=0 if no parameter was specified or 1 if
                ;a parameter was given.  The parameter is stored in
                ;PAR_L (Low byte) and PAR_H (High byte).  The registers
                ;are not preserved by these routines.


;-------------------------------------------------------------------------;
; Disassemble the instruction pointed to by PAR_L and PAR_H               ;
; PAR_L and PAR_H are incremented to point to the next instruction        ;
;-------------------------------------------------------------------------;
DISINST:        LDA     PAR_H           ;Output address
                JSR     HEXOUT
                LDA     PAR_L
                JSR     HEXOUT
                LDA     #$20
                JSR     OPCHAR
                JSR     OPCHAR
                LDY     #$00            ;Get op-code
                LDA     (PAR_L),Y
                PHA                     ;Save it
                INY                     ;Point to next byte
                TAX
                LDA     MNEM4,X         ;Get addressing mode...
                STA     GP2             ;...and store it
                AND     #$03            ;Get number of bytes in instruction...
                STA     GP1             ;...and store it
                TAX
                LDY     #$00
DISINST1:       LDA     (PAR_L),Y
                INY
                JSR     HEXOUT
                LDA     #$20
                JSR     OPCHAR
                DEX
                BPL     DISINST1
DISINST2:       SEC                     ;Tab to mnemonic column
                LDA     #$03
                SBC     GP1
                TAX
                BEQ     DISINST4
DISINST3:       LDA     #$20
                JSR     OPCHAR
                JSR     OPCHAR
                JSR     OPCHAR
                DEX
                BNE     DISINST3
DISINST4:       PLA                     ;Get instruction
                TAY
                LDA     MNEM1,Y         ;Output instruction mnemonic
                JSR     OPCHAR
                LDA     MNEM2,Y
                JSR     OPCHAR
                LDA     MNEM3,Y
                JSR     OPCHAR
                LDA     #$20
                JSR     OPCHAR
                LDA     GP2             ;Output instruction operand
                TAX
                AND     #$08            ;Output a "A"?
                BEQ     DISINST7
                LDA     #'A'
                JSR     OPCHAR
DISINST7:       TXA                     ;Output a "#"?
                AND     #$10
                BEQ     DISINST5
                LDA     #'#'
                JSR     OPCHAR
DISINST5:       TXA                     ;Output a "("?
                AND     #$20
                BEQ     DISINST6
                LDA     #'('
                JSR     OPCHAR
DISINST6:       TXA                     ;Output the required parameter
                AND     #$07
                BNE     DISINST21
                JMP     DISINST8
DISINST21:      PHA
                TXA
                PLA
                CMP     #$05
                BNE     DISINST13
                LDY     #$01            ;Offset addressing
                LDA     #'$'            ;Output a "$"
                JSR     OPCHAR
                LDA     (PAR_L),Y
                BMI     DISINST14
                CLC
                ADC     #$02
                CLC
                ADC     PAR_L
                PHA
                LDA     PAR_H
                ADC     #$00
                JSR     HEXOUT
                PLA
                JSR     HEXOUT
                JMP     DISINST8
DISINST14:      CLC
                LDA     PAR_L
                ADC     #$02
                LDY     #$01
                ADC     (PAR_L),Y
                PHA
                LDA     PAR_H
                SBC     #$00
                JSR     HEXOUT
                PLA
                JSR     HEXOUT
                JMP     DISINST8
DISINST13:      CMP     #$02            ;Normal addressing
                BEQ     DISINST22
                LDA     #'$'            ;One byte - Output a "$"
                JSR     OPCHAR
                JMP     DISINST9        ;Output byte
DISINST22:      TXA                     ;2 byte address = known label?
                PHA
                LDX     #$00
DISINST17:      LDY     #$01
                LDA     DADDR,X         ;End of table?
                AND     DADDR+1,X
                CMP     #$FF
                BEQ     DISINST18
                LDA     (PAR_L),Y
                CMP     DADDR,X
                BNE     DISINST15
                INY
                LDA     (PAR_L),Y
                CMP     DADDR+1,X
                BEQ     DISINST16
DISINST15:      INX
                INX
                BNE     DISINST17
DISINST16:      TXA                     ;Output known label
                ASL     A
                ASL     A
                TAX
                BCC     DISINST20
DISINST23:      LDA     DLABEL+$0100,X
                CMP     #$20
                BEQ     DISINST19
                JSR     OPCHAR
                INX
                BNE     DISINST23
DISINST20:      LDA     DLABEL,X
                CMP     #$20
                BEQ     DISINST19
                JSR     OPCHAR
                INX
                BNE     DISINST20
DISINST19:      PLA
                TAX
                JMP     DISINST8
DISINST18:      PLA                     ;Unknown address...
                TAX
                LDA     #'$'            ;Output a "$"
                JSR     OPCHAR
                LDY     #$02
                LDA     (PAR_L),Y
                JSR     HEXOUT
DISINST9:       LDY     #$01
                LDA     (PAR_L),Y
                JSR     HEXOUT
DISINST8:       TXA                     ;Output ",X"?
                AND     #$80
                BEQ     DISINST10
                LDA     #','
                JSR     OPCHAR
                LDA     #'X'
                JSR     OPCHAR
DISINST10:      TXA                     ;Output a ")"?
                AND     #$20
                BEQ     DISINST11
                LDA     #')'
                JSR     OPCHAR
DISINST11:      TXA
                AND     #$40            ;Output ",Y"?
                BEQ     DISINST12
                LDA     #','
                JSR     OPCHAR
                LDA     #'Y'
                JSR     OPCHAR
DISINST12:      JSR     NEWLINE         ;End of line
                INX
                TXA
                AND     #$03            ;Increment PAR_L,PAR_H to next inst.
                CLC
                ADC     PAR_L
                STA     PAR_L
                LDA     PAR_H
                ADC     #$00
                STA     PAR_H
                RTS


;-------------------------------------------------------------------------;
; Display registers on screen                                             ;
;-------------------------------------------------------------------------;
DISPREG:        PHA                     ;Save registers
                TXA
                PHA
                TYA
                PHA
                LDA     SCROLL          ;Save scroll flag
                PHA
                LDA     #$00            ;Disable scrolling
                STA     SCROLL
                JSR     CLEAR           ;Clear screen
                LDA     PSW
                AND     #$10
                BEQ     DISPREG2
                LDX     #>MSG9          ;Display "*BREAK*"
                LDY     #<MSG9
                JMP     DISPREG3
DISPREG2:       LDA     SINGLE
                BNE     DISPREG4
                LDX     #>MSG17         ;Display "*STOP*"
                LDY     #<MSG17
                JMP     DISPREG3
DISPREG4:       LDX     #>MSG16         ;Display "*STEP*"
                LDY     #<MSG16
DISPREG3:       JSR     STRING
                LDX     #$08            ;Display PSW in binary
                LDY     #$00
                LDA     #$00
                JSR     CURSOR          ;Position and hide cursor
                LDX     #$08            ;Set up 8 bits
                LDA     PSW             ;Load PSW into GP1
                STA     GP1
DISPREG1:       LDA     #$30            ;Load Acc with ASCII "0"
                ASL     GP1             ;Get next bit of PSW into carry
                ADC     #00             ;Add carry into accumulator
                JSR     OPCHAR          ;Display character
                DEX
                BNE     DISPREG1        ;Repeat for 8 bits
                LDX     #$00            ;Cursor to start of bottom line
                LDY     #$01
                LDA     #$00
                JSR     CURSOR
                LDA     PCHI            ;Display PC
                JSR     HEXOUT
                LDA     PCLO
                JSR     HEXOUT
                LDA     #$20            ;Display Acc
                JSR     OPCHAR
                LDA     ACC
                JSR     HEXOUT
                LDA     #$20            ;Display IX
                JSR     OPCHAR
                LDA     IX
                JSR     HEXOUT
                LDA     #$20            ;Display IY
                JSR     OPCHAR
                LDA     IY
                JSR     HEXOUT
                LDA     #$20            ;Display SP
                JSR     OPCHAR
                LDA     SP
                JSR     HEXOUT
                PLA                     ;Restore scroll flag
                STA     SCROLL
                PLA
                TAY
                PLA
                TAX
                PLA
                RTS


;-------------------------------------------------------------------------;
; Execute a program beginning at the specified address                    ;
;-------------------------------------------------------------------------;
C_GO:           CPX     #$01            ;Parameter passed?
                BEQ     GO3
                LDA     PCHI            ;No - copy old PC to parameter
                STA     PAR_H
                LDA     PCLO
                STA     PAR_L
GO3:            LDA     SINGLE          ;Set up single step
                BEQ     GO5
                STA     STLATCH
GO5:            LDX     #$00            ;Set up breakpoints
                LDY     #$00
GO1:            LDA     BPTAB,X
                ORA     BPTAB+1,X
                BEQ     GO2
                LDA     (BPTAB,X)
                STA     BPOPCODE,Y
                LDA     BPTAB,X         ;Breakpoint at start address?
                CMP     PCLO
                BNE     GO4
                LDA     BPTAB+1,X
                CMP     PCHI
                BEQ     GO2
GO4:            LDA     #$00            ;No - insert BRK instruction
                STA     (BPTAB,X)
GO2:            INX
                INX
                INY
                CPY     #$08
                BNE     GO1
                LDA     #$4C
                STA     GP1
                LDA     PAR_L
                STA     GP2
                LDA     PAR_H
                STA     GP3
                LDX     SP              ;Set up stack pointer
                TXS
                LDA     PSW             ;Push PSW on stack
                PHA
                LDX     IX              ;Set up IX
                LDY     IY              ;Set up IY
                LDA     ACC             ;Set up Acc
                PLP                     ;Set up PSW
                JMP     GP1             ;Execute program


;-------------------------------------------------------------------------;
; Turn single step on/off                                                 ;
;-------------------------------------------------------------------------;
C_STEP:         PHA
                TXA
                PHA
                TYA
                PHA
                LDX     #>MSG1          ;Display message
                LDY     #<MSG1
                JSR     STRING
                LDA     #$01            ;Toggle single step mode
                EOR     SINGLE
                STA     SINGLE
                BNE     STEP1           ;Single step now off?
                LDA     #$66            ;Yes - display "Off"
                JSR     OPCHAR
                JSR     OPCHAR
                JMP     STEP2
STEP1:          LDA     #$6E            ;No - display "On"
                JSR     OPCHAR
STEP2:          JSR     NEWLINE         ;New line
                PLA
                TAY
                PLA
                TAX
                PLA
                JMP     MONSTART        ;Re-enter monitor


;-------------------------------------------------------------------------;
; Set/clear breakpoints                                                   ;
;-------------------------------------------------------------------------;
C_BREAK:        CPX     #$00            ;Parameter specified?
                BNE     BREAK2
                LDA     #$00            ;No - Clear breakpoints
                LDX     #$0F
BREAK1:         STA     BPTAB,X
                DEX
                BPL     BREAK1
                LDX     #>MSG2
                LDY     #<MSG2
                JSR     STRING
                JMP     MONSTART        ;Re-enter monitor
BREAK2:         LDA     PAR_H           ;Yes - Parameter<=7?
                BNE     BREAK3
                LDA     PAR_L
                AND     #$07
                CMP     PAR_L
                BNE     BREAK3
                ASL     A               ;Yes - Clear specified breakpoint
                TAX
                LDA     #$00
                STA     BPTAB,X
                STA     BPTAB+1,X
                LDX     #>MSG3
                LDY     #<MSG3
                JSR     STRING
                LDA     PAR_L
                CLC
                ADC     #$30
                JSR     OPCHAR
                LDX     #>MSG5
                LDY     #<MSG5
                JSR     STRING
                JMP     MONSTART        ;Re-enter monitor
BREAK3:         LDX     #$00            ;No - find first available BP
BREAK5:         LDA     BPTAB,X
                ORA     BPTAB+1,X
                BEQ     BREAK4
                INX
                INX
                CPX     #$10
                BNE     BREAK5
                LDX     #>MSG6          ;None available, so return
                LDY     #<MSG6
                JSR     STRING
                JMP     MONSTART        ;Re-enter monitor
BREAK4:         LDA     PAR_L           ;Store BP address
                STA     BPTAB,X
                LDA     PAR_H
                STA     BPTAB+1,X
                TXA
                PHA
                LDX     #>MSG3          ;Display "BP "
                LDY     #<MSG3
                JSR     STRING
                PLA
                LSR     A
                CLC
                ADC     #$30            ;Display breakpoint number
                JSR     OPCHAR
                LDX     #>MSG4          ;Display " AT "
                LDY     #<MSG4
                JSR     STRING
                LDA     PAR_H           ;Display breakpoint address
                JSR     HEXOUT
                LDA     PAR_L
                JSR     HEXOUT
                JSR     NEWLINE
                JMP     MONSTART        ;Re-enter monitor


;-------------------------------------------------------------------------;
; Run demonstration                                                       ;
;-------------------------------------------------------------------------;
C_DEMO:         CPX     #$01            ;Parameter supplied?
                BEQ     C_DEMO1
C_DEMO2:        LDX     #>MSG8          ;No - display error message
                LDY     #<MSG8
                JSR     STRING
                JMP     MONSTART        ;Re-enter monitor
C_DEMO1:        LDA     PAR_L           ;Parameter in range?
                CMP     #$0A
                BPL     C_DEMO2
                JSR     CLEAR
                LDX     #>MSG7          ;Yes - Display demo. message
                LDY     #<MSG7
                JSR     STRING
                LDA     PAR_L
                JSR     HEXOUT
                JSR     NEWLINE
                LDA     PAR_L           ;Get vector address of demo.
                ASL     A
                CLC
                ADC     PAR_L
                ADC     #<DEMO0
                STA     PAR_L           ;Store address in PAR_L, PAR_H
                LDA     #$00
                ADC     #>DEMO0
                STA     PAR_H
                LDX     #$01
                JMP     C_GO            ;Execute "GO" command

;-------------------------------------------------------------------------;
; Display / modify memory                                                 ;
;-------------------------------------------------------------------------;
C_MODIFY:       LDY     #$00            ;Set byte modify offset to zero
MODIFYF:        TYA
                PHA
                JSR     CLEAR           ;Clear display
                LDA     #$00            ;Disable display scrolling
                STA     SCROLL
                LDA     PAR_H           ;Set up first display address
                STA     CMDPAR+1
                LDA     PAR_L
                STA     CMDPAR
                LDX     #$02            ;Repeat for two lines...
MODIFY2:        LDA     CMDPAR+1        ;Display first address
                JSR     HEXOUT
                LDA     CMDPAR
                JSR     HEXOUT
                LDY     #$00            ;Display contents of next 4 bytes
MODIFY1:        LDA     #$20
                JSR     OPCHAR
                LDA     (CMDPAR),Y
                JSR     HEXOUT
                INY
                CPY     #$04
                BNE     MODIFY1
                JSR     NEWLINE         ;Move to start of next line
                CLC                     ;Get address of next line
                LDA     CMDPAR
                ADC     #$04
                STA     CMDPAR
                LDA     CMDPAR+1
                ADC     #$00
                STA     CMDPAR+1
                DEX                     ;Decrement line counter
                BNE     MODIFY2
                PLA
                TAY
MODIFY3:        TYA                     ;Save byte offset
                PHA
                LDA     MODTABX,Y       ;Get cursor address
                TAX
                LDA     MODTABY,Y
                TAY
                LDA     #$01
                JSR     CURSOR          ;Move cursor
                PLA                     ;Restore byte offset
                TAY
                JSR     KBWAIT          ;Wait for key press
MODIFYD:        CMP     #KEYENT         ;ENTER pressed?
                BNE     MODIFY4
                INY                     ;Yes - increment byte offset by 1
MODIFY4:        CMP     #KEYDEL         ;DEL pressed?
                BNE     MODIFY5
                DEY                     ;Yes - decrement byte offset by 1
MODIFY5:        CMP     #KEYDOWN        ;DOWN pressed?
                BNE     MODIFY6
                INY                     ;Yes - increment byte offset by 4
                INY
                INY
                INY
MODIFY6:        CMP     #KEYUP          ;UP pressed?
                BNE     MODIFY7
                DEY                     ;Yes - decrement byte offset by 4
                DEY
                DEY
                DEY
MODIFY7:        CMP     #KEYESC         ;ESC pressed?
                BNE     MODIFYA
                JSR     CLEAR           ;Yes - clear screen...
                JMP     MONSTART        ;...and re-start monitor
MODIFYA:        CMP     #$30            ;Valid hexadecimal character?
                BMI     MODIFY8
                CMP     #$47
                BPL     MODIFY8
                STA     CMDPAR          ;Yes - store it
                JSR     OPCHAR          ;Display it
                JSR     KBWAIT          ;Wait for next key press
                CMP     #$30            ;Valid hexadecimal character?
                BMI     MODIFYB
                CMP     #$47
                BPL     MODIFYB
                STA     CMDPAR+1        ;Yes - store it
                JSR     OPCHAR          ;Display it
                TYA
                PHA
                LDY     #$02            ;Convert ASCII input into binary
                LDA     #CMDPAR
                JSR     HEXIN
                STY     GP1
                PLA                     ;Store result in memory
                TAY
                LDA     GP1
                STA     (PAR_L),Y
                INY
                JMP     MODIFY8
MODIFYB:        PHA                     ;Second key invalid
                TYA
                PHA
                LDA     #$30
                STA     CMDPAR+1        ;Store upper nybble only
                LDY     #$02
                LDA     #CMDPAR
                JSR     HEXIN
                STY     GP1
                PLA
                TAY
                LDA     #$0F
                AND     (PAR_L),Y
                ORA     GP1
                STA     (PAR_L),Y
                PLA                     ;Restore key code
                JMP     MODIFYD         ;Process key
MODIFY8:        CPY     #$00            ;Byte offset still on screen?
                BMI     MODIFY9
                CPY     #$08
                BPL     MODIFYE         ;Yes - wait for next key
                JMP     MODIFY3
MODIFYE:        CLC                     ;No - byte offset off bottom line...
                LDA     PAR_L           ;...add 4 to start address
                ADC     #$04
                STA     PAR_L
                LDA     PAR_H
                ADC     #$00
                STA     PAR_H
                DEY
                DEY
                DEY
                DEY
                JMP     MODIFYF         ;Display new lines
MODIFY9:        SEC                     ;Byte offset off top line...
                LDA     PAR_L           ;...subtract 4 from start address
                SBC     #$04
                STA     PAR_L
                LDA     PAR_H
                SBC     #$00
                STA     PAR_H
                INY
                INY
                INY
                INY
                JMP     MODIFYF         ;Display new lines


;-------------------------------------------------------------------------;
; Display / modify registers                                              ;
;-------------------------------------------------------------------------;
C_REGS:         LDA     #$00            ;Set pointer to first register
                STA     PAR_L
REGS1:          LDX     #$00            ;Cursor to start of bottom line
                LDY     #$01
                LDA     #$01
                JSR     CURSOR
                LDA     PAR_L           ;Display register name
                ASL     A
                TAX
                LDA     REGTAB1,X
                TAY
                LDA     REGTAB1+1,X
                TAX
                JSR     STRING
                LDA     CURX            ;Save cursor position
                PHA
                LDX     PAR_L
                LDA     REGTAB3,X       ;Get register length
                PHA
                LDA     REGTAB2,X       ;Get register address
                TAX
                PLA
                CMP     #$4
                BNE     REGS2
                LDA     $01,X           ;Two byte reg. - display high byte
                JSR     HEXOUT
REGS2:          LDA     $00,X           ;Display (low byte of) register
                JSR     HEXOUT
                LDA     #$20            ;Remove any extra characters
                JSR     OPCHAR
                JSR     OPCHAR
                PLA                     ;Move cursor to start of register
                TAX
                LDY     CURY
                LDA     CURSTAT
                JSR     CURSOR
                LDY     #$00            ;Get user input
REGS3:          JSR     KBWAIT          ;Wait for key press
                CMP     #KEYESC         ;ESC pressed?
                BNE     REGS4
                JMP     MONSTART        ;Yes - restart monitor
REGS4:          CMP     #KEYENT         ;ENTER pressed?
                BNE     REGS5
                CPY     #$00            ;New value entered?
                BEQ     REGS7
                LDA     #CMDPAR         ;Yes - convert ASCII to binary
                JSR     HEXIN
                TXA                     ;Store new register value
                PHA
                LDX     PAR_L
                LDA     REGTAB2,X
                TAX                     ;Get register address in IX
                STY     $00,X           ;Store low byte of result
                LDY     PAR_L           ;Two byte register?
                LDA     REGTAB3,Y
                CMP     #$04
                BNE     REGS7
                PLA                     ;Yes - store high byte
                STA     $01,X
REGS7:          INC     PAR_L           ;Point to next register
                LDA     PAR_L
                CMP     #$6
                BEQ     C_REGS          ;Repeat for new register
                BNE     REGS1
REGS5:          CMP     #KEYDEL         ;DEL pressed?
                BNE     REGS6
                CPY     #$00            ;Yes - Buffer already empty?
                BEQ     REGS3           ;Yes - ignore key
                JSR     OPCHAR          ;Delete character from screen
                DEY                     ;Decrement buffer pointer
                BPL     REGS3           ;Get next key press
REGS6:          CMP     #$30            ;Valid hexadecimal character?
                BMI     REGS3           ;No - ignore it
                CMP     #$47
                BPL     REGS3
                PHA
                LDX     PAR_L           ;Yes - Input buffer full?
                LDA     REGTAB3,X
                STA     GP1
                PLA
                CPY     GP1
                BEQ     REGS3           ;Yes - Ignore key
                JSR     OPCHAR          ;No - display key
                STA     CMDPAR,Y        ;Store key in input buffer
                INY                     ;Increment input buffer pointer
                BPL     REGS3           ;Get next key


;-------------------------------------------------------------------------;
; Request parameter                                                       ;
;-------------------------------------------------------------------------;
GETPARM:        LDY     #$00
GETPARM1:       JSR     KBWAIT          ;Valid command, get next key
                CMP     #KEYESC         ;ESC pressed?
                BEQ     GETPARM4        ;Yes - exit
                CMP     #KEYENT         ;ENTER pressed?
                BEQ     GETPARM3
                CMP     #KEYDEL         ;Delete pressed?
                BNE     GETPARM2        ;Yes...
                CPY     #$00            ;Input buffer empty?
                BEQ     GETPARM4        ;Yes - ignore delete request
                JSR     OPCHAR          ;Delete character on screen
                DEY                     ;Decrement input buffer pointer
                BPL     GETPARM1        ;Get next key
GETPARM2:       CMP     #$30            ;Valid hex. character?
                BMI     GETPARM1        ;No - get another
                CMP     #$47
                BPL     GETPARM1
                CPY     #$04            ;Input buffer full?
                BEQ     GETPARM1        ;Yes - ignore key
                STA     CMDPAR,Y        ;No - store key
                JSR     OPCHAR          ;Display key
                INY                     ;Increment input buffer pointer
                BNE     GETPARM1        ;Get next key
GETPARM3:       TYA
                BEQ     GETPARM5
                PHA
                LDA     #CMDPAR         ;Get start address of parameter
                JSR     HEXIN           ;Convert ASCII into binary
                PLA                     ;Store number of characters in Acc
GETPARM5:       SEC
                RTS
GETPARM4:       CLC
                RTS


;-------------------------------------------------------------------------;
; Transfer a block of memory                                              ;
;-------------------------------------------------------------------------;

C_XFR:          LDX     #>MSG19         ;Request end address
                LDY     #<MSG19
                JSR     STRING
                JSR     GETPARM         ;Get end address
                BCS     XFR9
                JMP     XFR8
XFR9:           TXA                     ;Save end address on stack
                PHA
                TYA
                PHA
                JSR     NEWLINE
                LDX     #>MSG24         ;Request destination address
                LDY     #<MSG24
                JSR     STRING
                JSR     GETPARM         ;Start addr in PAR_L,PAR_H
                BCS     XFR10
                JMP     XFR8
XFR10:          STY     CMDPAR          ;Dest addr in CMDPAR,CMDPAR+1
                STX     CMDPAR+1
                PLA                     ;End addr in CMDPAR+2,CMDPAR+3
                STA     CMDPAR+2
                PLA
                STA     CMDPAR+3
                LDY     #$00
                LDA     CMDPAR+1        ;Determine block copy direction
                CMP     PAR_H
                BEQ     XFR1
                BCS     XFR2
                BCC     XFR4
XFR1:           LDA     CMDPAR
                CMP     PAR_L
                BCS     XFR2
XFR4:           LDA     (PAR_L),Y       ;Transfer block from start to end
                STA     (CMDPAR),Y
                LDA     PAR_L           ;Finished?
                CMP     CMDPAR+2
                BNE     XFR3
                LDA     PAR_H
                CMP     CMDPAR+3
                BNE     XFR3            ;Yes - Jump to end
                JMP     XFR5
XFR3:           CLC                     ;Increment addresses
                LDA     PAR_L
                ADC     #$01
                STA     PAR_L
                LDA     PAR_H
                ADC     #$00
                STA     PAR_H
                CLC
                LDA     CMDPAR
                ADC     #$01
                STA     CMDPAR
                LDA     CMDPAR+1
                ADC     #$00
                STA     CMDPAR+1
                JMP     XFR4
XFR2:           SEC                     ;Transfer block from end to start
                LDA     CMDPAR+2
                SBC     PAR_L
                PHP
                CLC
                ADC     CMDPAR
                STA     CMDPAR
                PHP
                PLA
                TAX
                PLP
                LDA     CMDPAR+3
                SBC     PAR_H
                TAY
                TXA
                PHA
                PLP
                TYA
                ADC     CMDPAR+1
                STA     CMDPAR+1
XFR7:           LDA     (CMDPAR+2),Y    
                STA     (CMDPAR),Y
                LDA     PAR_L           ;Finished?
                CMP     CMDPAR+2
                BNE     XFR6
                LDA     PAR_H
                CMP     CMDPAR+3
                BEQ     XFR5            ;Yes - Jump to end
XFR6:           SEC                     ;Decrement addresses
                LDA     CMDPAR+2
                SBC     #$01
                STA     CMDPAR+2
                LDA     CMDPAR+3
                SBC     #$00
                STA     CMDPAR+3
                SEC
                LDA     CMDPAR
                SBC     #$01
                STA     CMDPAR
                LDA     CMDPAR+1
                SBC     #$00
                STA     CMDPAR+1
                JMP     XFR7
XFR5:           JSR     NEWLINE         ;Yes - return to monitor
XFR8:           JMP     MONSTART


;-------------------------------------------------------------------------;
; Calculate the offset for a branch instruction                           ;
;-------------------------------------------------------------------------;
C_OFFSET:       LDX     #>MSG21         ;Request branch address
                LDY     #<MSG21
                JSR     STRING
                JSR     GETPARM         ;Get end address
                BCC     OFFSET3
                STY     CMDPAR          ;Store end address
                STX     CMDPAR+1
                JSR     NEWLINE
                CLC
                LDA     PAR_L
                ADC     #$02
                STA     PAR_L
                LDA     PAR_H
                ADC     #$00
                STA     PAR_H
                SEC
                LDA     CMDPAR
                SBC     PAR_L
                STA     PAR_L
                LDA     CMDPAR+1
                SBC     PAR_H
                STA     PAR_H
                BEQ     OFFSET2
                CMP     #$FF
                BEQ     OFFSET2
                CMP     #$01
                BNE     OFFSET1
OFFSET2:        EOR     PAR_L
                BMI     OFFSET1
                LDX     #>MSG22
                LDY     #<MSG22
                JSR     STRING
                LDA     PAR_L
                JSR     HEXOUT
                JSR     NEWLINE
                JMP     MONSTART
OFFSET1:        LDX     #>MSG23
                LDY     #<MSG23
                JSR     STRING
OFFSET3:        JMP     MONSTART

;-------------------------------------------------------------------------;
; Hex dump a block of memory to the printer or UART                       ;
;-------------------------------------------------------------------------;
C_HEXDUMP:      LDX     #>MSG19         ;Request end address
                LDY     #<MSG19
                JSR     STRING
                JSR     GETPARM         ;Get end address
                BCS     HEXDUMP8
                JMP     HEXDUMP7
HEXDUMP8:       STY     CMDPAR          ;Store end address
                STX     CMDPAR+1
                JSR     NEWLINE
                LDX     #>MSG18         ;Display "Printing..."
                LDY     #<MSG18
                JSR     STRING
                JSR     PINIT           ;Initialise 65C22 for printing
HEXDUMP1:       LDA     PRDEV           ;Enable LCD
                STA     OPREG
                JSR     NEWLINE         ;Start printing on a new line
                LDA     CONSOLE
                STA     OPREG
                LDA     #$0D
                JSR     OPCHAR
                LDA     CONSOLE
                ORA     PRDEV
                STA     OPREG
                LDA     PAR_H           ;Print address
                JSR     HEXOUT
                LDA     PAR_L
                JSR     HEXOUT
                LDA     PRDEV           ;Enable printer output only
                STA     OPREG
                LDA     #$20            ;Print two spaces
                JSR     OPCHAR
                JSR     OPCHAR
                LDY     #$00            ;Point to first byte on line
HEXDUMP2:       LDA     (PAR_L),Y       ;Get value of next byte
                JSR     HEXOUT          ;Print it in hex.
                LDA     #$20            ;Print a space
                JSR     OPCHAR
                INY                     ;Point to next byte on line
                CPY     #$10            ;Done 16 bytes?
                BNE     HEXDUMP2        ;No - do the next one
                LDA     #$20            ;Print a space
                JSR     OPCHAR
                LDY     #$00            ;Point to first byte on line
HEXDUMP3:       LDA     (PAR_L),Y       ;Get value of next byte
                AND     #$7F            ;Strip off bit 8
                CMP     #$20            ;Printable character?
                BPL     HEXDUMP4
                LDA     #$2E            ;No - use a "."
HEXDUMP4:       CMP     #$7F
                BNE     HEXDUMP5
                LDA     #$2E
HEXDUMP5:       JSR     OPCHAR           ;Print it
                INY                     ;Point to next byte on line
                CPY     #$10            ;Done 16 bytes?
                BNE     HEXDUMP3        ;No - do the next one
                CLC                     ;Add 16 to line address
                LDA     PAR_L
                ADC     #$10
                STA     PAR_L
                LDA     PAR_H
                ADC     #$00
                STA     PAR_H
                LDA     CMDPAR+1        ;End address < current address?
                CMP     PAR_H
                BEQ     HEXDUMP6
                BCS     HEXDUMP1
HEXDUMP6:       LDA     CMDPAR
                CMP     PAR_L
                BCS     HEXDUMP1
                LDA     PRDEV
                ORA     CONSOLE
                STA     OPREG
                JSR     NEWLINE         ;Yes - finish
                JSR     NEWLINE
                LDA     CONSOLE         ;Set output to LCD only
                STA     OPREG
                LDA     #'O'
                JSR     OPCHAR
                LDA     #'K'
                JSR     OPCHAR
                JSR     NEWLINE
HEXDUMP7:       JMP     MONSTART


;-------------------------------------------------------------------------;
; Disassemble an area of memory to the printer                            ;
;-------------------------------------------------------------------------;
C_PDIS:         LDX     #>MSG19         ;Request end address
                LDY     #<MSG19
                JSR     STRING
PDIS2:          JSR     GETPARM         ;Get end address
                BCC     PDIS4
                BCC     PDIS2
                STY     CMDPAR          ;Store end address
                STX     CMDPAR+1
                JSR     NEWLINE
                LDX     #>MSG18         ;Display "Printing..."
                LDY     #<MSG18
                JSR     STRING
                JSR     PINIT           ;Initialise 65C22 for printing
                LDA     PRDEV
                STA     OPREG
                JSR     NEWLINE         ;Start printing on a new line
PDIS1:          LDA     CONSOLE
                STA     OPREG
                LDA     #$0D            ;Cursor on start of line
                JSR     OPCHAR
                LDA     PAR_H           ;Display address
                JSR     HEXOUT
                LDA     PAR_L
                JSR     HEXOUT
                LDA     PRDEV
                STA     OPREG
                JSR     DISINST         ;Disassemble next instruction
                LDA     CMDPAR+1        ;End address < current address?
                CMP     PAR_H
                BEQ     PDIS3
                BCS     PDIS1
PDIS3:          LDA     CMDPAR
                CMP     PAR_L
                BCS     PDIS1
                LDA     PRDEV
                ORA     CONSOLE
                STA     OPREG
                JSR     NEWLINE         ;Yes - finish
                JSR     NEWLINE
                LDA     CONSOLE
                STA     OPREG
                LDA     #'O'
                JSR     OPCHAR
                LDA     #'K'
                JSR     OPCHAR
                JSR     NEWLINE
PDIS4:          JMP     MONSTART


;-------------------------------------------------------------------------;
; Select an external (terminal) device for monitor input and output       ;
;-------------------------------------------------------------------------;
C_EXTCON:       JMP     MONSTART


;-------------------------------------------------------------------------;
; Select a printing device                                                ;
;-------------------------------------------------------------------------;
C_PDEV:         LDX     PAR_L           ;Get parameter
                BEQ     PDEV1
                LDX     #>MSG25         ;If not zero, use serial printer
                LDY     #<MSG25
                JSR     STRING
                LDA     #$04
                JMP     PDEV2
PDEV1:          LDX     #>MSG26         ;If zero, use parallel printer
                LDY     #<MSG26
                JSR     STRING
                LDA     #$02
PDEV2:          STA     PRDEV
                LDX     #>MSG27
                LDY     #<MSG27
                JSR     STRING
                JMP     MONSTART


;-------------------------------------------------------------------------;
; Machine code monitor - main routine                                     ;
;-------------------------------------------------------------------------;
SHOWREG:        LDA     CONSOLE         ;Output to console only
                STA     OPREG
                JSR     DISPREG         ;Yes - display them
MONITORA:       LDA     KBSIZE          ;Wait for key to be pressed
                BEQ     MONITORA
                JSR     CLEAR           ;Clear display
MONSTART:       LDA     CONSOLE
                STA     OPREG
                CLD
                LDX     #$00            ;Hide and position cursor at left
                LDY     CURY
                LDA     #$00
                JSR     CURSOR
                LDX     #$10            ;Clear display line
                LDA     #$20
MONITOR1:       JSR     LCDWRITE
                DEX
                BNE     MONITOR1
                LDA     #$01            ;Show cursor
                JSR     CURSOR
                LDA     #$01            ;Enable display scrolling
                STA     SCROLL
                LDA     #$3E            ;Display prompt
                JSR     OPCHAR
MONITOR4:       JSR     KBWAIT          ;Wait for command
                LDX     #NUMCMDS        ;Get command number
MONITOR2:       CMP     VALIDCMD,X
                BEQ     MONITOR3
                DEX
                BPL     MONITOR2
                BMI     MONITOR4        ;Invalid command - get another
MONITOR3:       STX     CMD             ;Save command number
                TXA                     ;Display command message
                ASL     A
                ASL     A
                ASL     A
                CLC
                ADC     #<CMDSTR
                TAY
                LDA     #$00
                ADC     #>CMDSTR
                TAX
                JSR     STRING
                JSR     GETPARM
                BCC     MONSTART
                STX     PAR_H           ;Store parameter
                STY     PAR_L
                LDX     #$00
                CMP     #$00            ;Parameter entered?
                BEQ     MONITOR8
                LDX     #$01            ;Indicate parameter entered
MONITOR8:       JSR     NEWLINE         ;Cursor on new line
                LDA     CMD             ;Get address of command routine
                ASL     A
                TAY
                LDA     #$4C
                STA     GP1
                LDA     CMDADDR,Y
                STA     GP2
                LDA     CMDADDR+1,Y
                STA     GP3
                JMP     GP1             ;Execute command


;-------------------------------------------------------------------------;
; Initialise operating system functions                                   ;
;-------------------------------------------------------------------------;
OSINIT:         PHA                     ;Save registers
                TXA
                PHA
                LDA     #$00            ;Clear breakpoints
                LDX     #$0F
OSINIT1:        STA     BPTAB,X
                DEX
                BPL     OSINIT1
                STA     SINGLE          ;Single step off
                LDA     #$FF
                STA     SP
                LDA     #$02            ;Select parallel printer output
                STA     PRDEV
                LDA     #$01            ;Select LCD/Keypad
                STA     CONSOLE
                LDX     #>OSMSG         ;Display O/S installed message
                LDY     #<OSMSG
                JSR     STRING
                LDA     #20             ;Wait 200mS
                JSR     DELAY
                PLA                     ;Restore registers
                TAX
                PLA
                RTS


;-------------------------------------------------------------------------;
; Valid command keys                                                      ;
;-------------------------------------------------------------------------;
VALIDCMD:       DFB     KEYGO, KEYMOD, KEYSTEP, KEYREG
                DFB     KEYBRK, KEYDEMO, KEYDUMP, KEYPDIS
                DFB     KEYOFS, KEYXFR, KEYPDEV, KEYCON


;-------------------------------------------------------------------------;
; Command routine address table                                           ;
;-------------------------------------------------------------------------;
CMDADDR:        DFW     C_GO
                DFW     C_MODIFY
                DFW     C_STEP
                DFW     C_REGS
                DFW     C_BREAK
                DFW     C_DEMO
                DFW     C_HEXDUMP
                DFW     C_PDIS
                DFW     C_OFFSET
                DFW     C_XFR
                DFW     C_PDEV
                DFW     C_EXTCON


;-------------------------------------------------------------------------;
; Command strings                                                         ;
;-------------------------------------------------------------------------;
CMDSTR:         DFM     'GO '
                DFB     0,0,0,0,0
                DFM     'MODIFY '
                DFB     0
                DFM     'STEP '
                DFB     0,0,0
                DFM     'REGS '
                DFB     0,0,0
                DFM     'BREAK '
                DFB     0,0
                DFM     'DEMO '
                DFB     0,0,0
                DFM     'HEXDMP '
                DFB     0
                DFM     'DISASM '
                DFB     0
                DFM     'OFFSET '
                DFB     0
                DFM     'XFR '
                DFB     0,0,0,0
                DFM     'PDEV '
                DFB     0,0,0
                DFM     'EXTCON '
                DFB     0


;-------------------------------------------------------------------------;
; Modify command cursor position table                                    ;
;-------------------------------------------------------------------------;
MODTABX:        DFB     $05,$08,$0B,$0E,$05,$08,$0B,$0E
MODTABY:        DFB     $00,$00,$00,$00,$01,$01,$01,$01


;-------------------------------------------------------------------------;
; Register modify: message table                                          ;
;-------------------------------------------------------------------------;
REGTAB1:        DFW     MSG10
                DFW     MSG11
                DFW     MSG12
                DFW     MSG13
                DFW     MSG14
                DFW     MSG15


;-------------------------------------------------------------------------;
; LED Bargraph Table                                                      ;
;-------------------------------------------------------------------------;
LEDBAR:         DFB     $FE, $FC, $F8, $F0, $E0, $C0, $80, $00


;-------------------------------------------------------------------------;
; Register modify: register address table                                 ;
;-------------------------------------------------------------------------;
REGTAB2:        DFB     ACC,IX,IY,PCLO,SP,PSW


;-------------------------------------------------------------------------;
; Register modify: register length table                                  ;
;-------------------------------------------------------------------------;
REGTAB3:        DFB     2,2,2,4,2,2


;-------------------------------------------------------------------------;
; Table of vectored BIOS function calls, used when initialising system    ;
;-------------------------------------------------------------------------;
VECTAB:         JMP     B_INT
                JMP     B_NMI
                JMP     B_OPCHAR
                JMP     B_CURSOR
                JMP     B_CLEAR
                JMP     B_NEWLINE
                JMP     B_POSCHAR
                JMP     B_SOUND
                JMP     B_DELAY
                JMP     B_KBWAIT
                JMP     B_KBLAST
                JMP     B_KBCLR
                JMP     B_HEXOUT
                JMP     B_HEXIN
                JMP     B_STRING
                JMP     B_PCHAR
                JMP     B_PINIT
                JMP     B_LCDCHAR
                DFB     $00


;-------------------------------------------------------------------------;
; Demonstration routine vectors                                           ;
;-------------------------------------------------------------------------;
DEMO0:          JMP     D_DEMO0
DEMO1:          JMP     D_DEMO1
DEMO2:          JMP     D_DEMO2
DEMO3:          JMP     D_DEMO3
DEMO4:          JMP     D_DEMO4
DEMO5:          JMP     D_DEMO5
DEMO6:          JMP     D_DEMO6
DEMO7:          JMP     D_DEMO7
DEMO8:          JMP     D_DEMO8
DEMO9:          JMP     D_DEMO9


;-------------------------------------------------------------------------;
; 6502 Assembler mnemonics                                                ;
;-------------------------------------------------------------------------;
MNEM1:          DFM     'BO???OA?POA??OA?'      ;First characters
                DFM     'BO???OA?CO???OA?'
                DFM     'JA??BAR?PAR?BAR?'
                DFM     'BA???AR?SA???AR?'
                DFM     'RE???EL?PEL?JEL?'
                DFM     'BE???EL?CE???EL?'
                DFM     'RA???AR?PAR?JAR?'
                DFM     'BA???AR?SA???AR?'
                DFM     '?S??SSS?D?T?SSS?'
                DFM     'BS??SSS?TST??S??'
                DFM     'LLL?LLL?TLT?LLL?'
                DFM     'BL??LLL?CLT?LLL?'
                DFM     'CC??CCD?ICD?CCD?'
                DFM     'BC???CD?CC???CD?'
                DFM     'CS??CSI?ISN?CSI?'
                DFM     'BS???SI?SS???SI?'
MNEM2:          DFM     'RR???RS?HRS??RS?'      ;Second characters
                DFM     'PR???RS?LR???RS?'
                DFM     'SN??INO?LNO?INO?'
                DFM     'MN???NO?EN???NO?'
                DFM     'TO???OS?HOS?MOS?'
                DFM     'VO???OS?LO???OS?'
                DFM     'TD???DO?LDO?MDO?'
                DFM     'VD???DO?ED???DO?'
                DFM     '?T??TTT?E?X?TTT?'
                DFM     'CT??TTT?YTX??T??'
                DFM     'DDD?DDD?ADA?DDD?'
                DFM     'CD??DDD?LDS?DDD?'
                DFM     'PM??PME?NME?PME?'
                DFM     'NM???ME?LM???ME?'
                DFM     'PB??PBN?NBO?PBN?'
                DFM     'EB???BN?EB???BN?'
MNEM3:          DFM     'KA???AL?PAL??AL?'      ;Third Characters
                DFM     'LA???AL?CA???AL?'
                DFM     'RD??TDL?PDL?TDL?'
                DFM     'ID???DL?CD???DL?'
                DFM     'IR???RR?ARR?PRR?'
                DFM     'CR???RR?IR???RR?'
                DFM     'SC???CR?ACR?PCR?'
                DFM     'SC???CR?IC???CR?'
                DFM     '?A??YAX?Y?A?YAX?'
                DFM     'CA??YAX?AAS??A??'
                DFM     'YAX?YAX?YAX?YAX?'
                DFM     'SA??YAX?VAX?YAX?'
                DFM     'YP??YPC?YPX?YPC?'
                DFM     'EP???PC?DP???PC?'
                DFM     'XC??XCC?XCP?XCC?'
                DFM     'QC???CC?DC???CC?'
MNEM4:          DFB     $00,$A1,$00,$00,$00,$01,$01,$00
                DFB     $00,$11,$08,$00,$00,$02,$02,$00
                DFB     $05,$61,$00,$00,$00,$81,$81,$00
                DFB     $00,$42,$00,$00,$00,$82,$82,$00
                DFB     $02,$A1,$00,$00,$01,$01,$01,$00
                DFB     $00,$11,$08,$00,$02,$02,$02,$00
                DFB     $05,$61,$00,$00,$00,$81,$81,$00
                DFB     $00,$42,$00,$00,$00,$82,$82,$00
                DFB     $00,$A1,$00,$00,$00,$01,$01,$00
                DFB     $00,$11,$08,$00,$02,$02,$02,$00
                DFB     $05,$61,$00,$00,$00,$81,$81,$00
                DFB     $00,$42,$00,$00,$00,$82,$82,$00
                DFB     $00,$A1,$00,$00,$00,$01,$01,$00
                DFB     $00,$11,$08,$00,$22,$02,$02,$00
                DFB     $05,$61,$00,$00,$00,$81,$81,$00
                DFB     $00,$42,$00,$00,$00,$82,$82,$00
                DFB     $00,$A1,$00,$00,$01,$01,$01,$00
                DFB     $00,$00,$00,$00,$02,$02,$02,$00
                DFB     $05,$61,$00,$00,$81,$81,$41,$00
                DFB     $00,$42,$00,$00,$00,$82,$00,$00
                DFB     $11,$A1,$11,$00,$01,$01,$01,$00
                DFB     $00,$11,$00,$00,$02,$02,$02,$00
                DFB     $05,$61,$00,$00,$81,$81,$41,$00
                DFB     $00,$42,$00,$00,$82,$82,$42,$00
                DFB     $11,$A1,$00,$00,$01,$01,$01,$00
                DFB     $00,$11,$00,$00,$02,$02,$02,$00
                DFB     $05,$61,$00,$00,$00,$81,$81,$00
                DFB     $00,$42,$00,$00,$00,$82,$82,$00
                DFB     $11,$A1,$00,$00,$01,$01,$01,$00
                DFB     $00,$11,$00,$00,$02,$02,$02,$00
                DFB     $05,$61,$00,$00,$00,$81,$81,$00
                DFB     $00,$42,$00,$00,$00,$82,$82,$00


;-------------------------------------------------------------------------;
; Assembler/Disassembler Monitor Address Labels                           ;
;-------------------------------------------------------------------------;
DLABEL:         DFM     'INTVEC  '
                DFM     'NMIVEC  '
                DFM     'OPCHAR  '
                DFM     'CURSOR  '
                DFM     'CLEAR   '
                DFM     'NEWLINE '
                DFM     'POSCHAR '
                DFM     'SOUND   '
                DFM     'DELAY   '
                DFM     'KBWAIT  '
                DFM     'KBLAST  '
                DFM     'KBCLR   '
                DFM     'HEXOUT  '
                DFM     'HEXIN   '
                DFM     'STRING  '
                DFM     'PCHAR   '
                DFM     'PINIT   '
                DFM     'LCDCHAR '
                DFM     'LED     '
                DFM     'DIPSW   '
                DFM     'AIN     '
                DFM     'AOUT    '
                DFM     'VIAr0   '
                DFM     'VIAr1   '
                DFM     'VIAr2   '
                DFM     'VIAr3   '
                DFM     'VIAr4   '
                DFM     'VIAr5   '
                DFM     'VIAr6   '
                DFM     'VIAr7   '
                DFM     'VIAr8   '
                DFM     'VIAr9   '
                DFM     'VIAr10  '
                DFM     'VIAr11  '
                DFM     'VIAr12  '
                DFM     'VIAr13  '
                DFM     'VIAr14  '
                DFM     'VIAr15  '
                DFM     'LCDCMD  '
                DFM     'LCDDTA  '
                DFM     'KBDTA   '
                DFM     'KBCMD   '
                DFM     'STLATCH '

DADDR:          DFW     INTVEC
                DFW     NMIVEC
                DFW     OPCHAR
                DFW     CURSOR
                DFW     CLEAR
                DFW     NEWLINE
                DFW     POSCHAR
                DFW     SOUND
                DFW     DELAY
                DFW     KBWAIT
                DFW     KBLAST
                DFW     KBCLR
                DFW     HEXOUT
                DFW     HEXIN
                DFW     STRING
                DFW     PCHAR
                DFW     PINIT
                DFW     LCDCHAR
                DFW     LED
                DFW     DIPSW
                DFW     AIN
                DFW     AOUT
                DFW     VIA
                DFW     VIA+1
                DFW     VIA+2
                DFW     VIA+3
                DFW     VIA+4
                DFW     VIA+5
                DFW     VIA+6
                DFW     VIA+7
                DFW     VIA+8
                DFW     VIA+9
                DFW     VIA+10
                DFW     VIA+11
                DFW     VIA+12
                DFW     VIA+13
                DFW     VIA+14
                DFW     VIA+15
                DFW     LCDCMD
                DFW     LCDDTA
                DFW     KBDTA
                DFW     KBCMD
                DFW     STLATCH
                DFW     $FFFF


;-------------------------------------------------------------------------;
; Keyboard character map                                                  ;
;-------------------------------------------------------------------------;
KBMAP:          DFB     $00, 'G', 'D', 'T', '0', $00, $00, $00
                DFB     $03, '#', 'H', 'P', '1', $00, $00, $00
                DFB     $0B, 'R', 'S', 'X', '2', $00, $00, $00
                DFB     $0A, 'M', 'B', 'O', '3', $00, $00, $00
                DFB     $00, $00, $00, $00, $00, $00, $00, $00
                DFB     $00, $00, $00, $00, $00, $00, $00, $00
                DFB     $00, $00, $00, $00, $00, $00, $00, $00
                DFB     $00, $00, $00, $00, $00, $00, $00, $00
                DFB     $00, 'C', '8', '4', '0', $00, $00, $00
                DFB     $1B, 'D', '9', '5', '1', $00, $00, $00
                DFB     $7F, 'E', 'A', '6', '2', $00, $00, $00
                DFB     $0D, 'F', 'B', '7', '3', $00, $00, $00
                DFB     $00, $00, $00, $00, $00, $00, $00, $00
                DFB     $00, $00, $00, $00, $00, $00, $00, $00
                DFB     $00, $00, $00, $00, $00, $00, $00, $00
                DFB     $00, $00, $00, $00, $00, $00, $00, $00


;-------------------------------------------------------------------------;
; Operating system messages                                               ;
;-------------------------------------------------------------------------;
MSG1:           DFM     'Single step o'
                DFB     $00
MSG2:           DFM     'All BPs cleared'
                DFB     $0D, $0A, $00
MSG3:           DFM     'BP '
                DFB     $00
MSG4:           DFM     ' at '
                DFB     $00
MSG5:           DFM     ' cleared'
                DFB     $0D, $0A, $00
MSG6:           DFM     '8 BPs set'
                DFB     $0D, $0A, $00
MSG7:           DFB     $0C
                DFM     'Demo '
                DFB     $00
MSG8:           DFM     'Invalid param.'
                DFB     $0D, $0A, $00
MSG9:           DFM     '*BREAK*'
                DFB     $00
MSG10:          DFM     'ACC='
                DFB     $00
MSG11:          DFM     ' IX='
                DFB     $00
MSG12:          DFM     ' IY='
                DFB     $00
MSG13:          DFM     ' PC='
                DFB     $00
MSG14:          DFM     ' SP='
                DFB     $00
MSG15:          DFM     'PSW='
                DFB     $00
MSG16:          DFM     '*STEP* '
                DFB     $00
MSG17:          DFM     '*STOP*'
                DFB     $00
MSG18:          DFM     'Printing...'
                DFB     $0D, $0A, $00
MSG19:          DFM     'End addr='
                DFB     $00
MSG20:          DFB     $0D, $0A
                DFM     'Printer Fault'
                DFB     $0D, $0A
                DFM     '[ENTER] / [ESC]'
                DFB     $00
MSG21:          DFM     'Branch to '
                DFB     $00
MSG22:          DFM     'Offset='
                DFB     $00
MSG23:          DFB     $0D
                DFM     'Range Error'
                DFB     $0D, $0A, $00
MSG24:          DFM     'Dest addr='
                DFB     $00
MSG25:          DFM     'Serial'
                DFB     $00
MSG26:          DFM     'Parallel'
                DFB     $00
MSG27:          DFM     ' print'
                DFB     $0D, $0A, $00
MSG28:          DFB     $0C
                DFM     'EXTERNAL CONSOLE'
                DFB     $00
MSG29:          DFM     'Testing Memory'
                DFB     $00
MSG30:          DFM     'Passed'
                DFB     $00
MSG31:          DFM     'Failed  [ENTER]'
                DFB     $00

;-------------------------------------------------------------------------;
; System initialisation messages                                          ;
;-------------------------------------------------------------------------;
BIOSMSG:        DFM     'BIOS Loaded'
                DFB     $0D, $0A, $00
OSMSG:          DFM     'O/S Loaded'
                DFB     $00
MONMSG:         DFB     $0D, $0A
                DFM     'Micro Lab V1.10'
                DFB     $00
CPYRT:          DFM     '(C) 1993 Geoff MacDonald'


;**************************************************************************
;*** SYSTEM ADDRESSES                                                   ***
;**************************************************************************

                @=$0FFFA
                DFW     NMIVEC
                DFW     RESET
                DFW     INTVEC

                END
