; ; Acorn monitor for Acorn System 6809 CPU card ; ; ISSUE 1 - V49 - FEB 1980 ; ; 2019-06-01 Source transcribed from Acorn 6809 User Manual by Keith Howell ; 2019-06-02 Ported for online assembler www.asm80.com ; 2019-07-04 Began changing to match program listing in manual looks a very ; long job and the code differs in places ; 2019-09-21 Tweeked for Kingston 6809 assembler by J.G.Harston ; Build with: as09-dos -i -h0 -w -lSys6809.lst -oSys6809.bin Sys6809.src ; ; Differences: ; Acorn assembler: Kingston assembler: ; Uses SETDP Uses DIRECT ; Forward references in LEA Forward references in LEA ; calculate short constants result in long constants ; Opcodes are valid as labels Opcodes are invalid as labels ; BSS marks data not to be saved ; CODE marks data to be saved ; ; If using an assembler that does not use BSS and CODE, comment them out where ; they occur. If using an assembler that uses SETDP, comment out the SETDP macro. ; ; If using an assembler that uses DIRECT, define SETDP macro SETDP MACRO dpvalue DIRECT dpvalue ENDM ; ; ; This program handles a memory mapped VDU, encoded keyboard, ; cassette interface, parallel printer, and mini-floppy bootstrap. ; MPROM EQU $F800 ; Normal monitor position at top of memory. MONDP EQU $0300/256 ; Direct page for monitor. ; ROWS EQU 25 ; Number of rows on display. COLS EQU 40 ; Number of characters per row. PSIZE EQU 1024 ; Size of display memory in total. VPAGE EQU $0400 ; Location of memory that VDU uses. CRTC EQU $0800 ; Location of CRT controller on VDU card. PAGHI EQU 12 ; Page address register, high byte. CURHI EQU 14 ; Cursor address register, high byte. ; DRIVE EQU $40 ; Drive to bootstrap from, other drive is $80. FLOPY EQU $0A00 ; Location of floppy disc controller. FDCC EQU FLOPY+0 ; Command register FDCS EQU FDCC ; Status register. FDCP EQU FLOPY+1 ; Parameter register FDCR EQU FDCP ; Result register. FDRST EQU FLOPY+2 ; Reset register. FDCD EQU FLOPY+4 ; Data register. ; KVIA EQU $0980 ; Location of versatile interface adaptor. KORB EQU KVIA+$0 ; Output register B. KIRB EQU KORB ; Input register B. KORA EQU KVIA+$1 ; Output register A. KIRA EQU KORA ; Input register A. KDDRB EQU KVIA+$2 ; Data direction register B. KDDRA EQU KVIA+$3 ; Data direction register A. KT1CL EQU KVIA+$4 ; Timer 1 counter low. KT1CH EQU KVIA+$5 ; Timer 1 counter high. KT1LL EQU KVIA+$6 ; Timer 1 latch low. KT1LH EQU KVIA+$7 ; Timer 1 latch high. KT2CL EQU KVIA+$8 ; Timer 2 counter low. KT2CH EQU KVIA+$9 ; Timer 2 counter high. KSR EQU KVIA+$A ; Shift register. KACR EQU KVIA+$B ; Auxiliary control register. KPCR EQU KVIA+$C ; Peripheral control register. KIFR EQU KVIA+$D ; Interrupt flag register. KIER EQU KVIA+$E ; Interrupt enable register. KORA2 EQU KVIA+$F ; Input/output register A without hand shake. ; INTDEL EQU 15*256 ; Delay for single instruction trace is 15 cycles. T1IFLG EQU %01000000 ; Interrupt flag position for timer 1. CB1FLG EQU %00010000 ; Interrupt flag position for keyboard strobe on CB1. ; IKPCR EQU %11101111 ; Initial value for peripheral control register, ; bit 0, CA1 control from printer, positive edge interrupt, ; but not used in this monitor. ; bits 1-3, CA2 control to strobe printer, normally high. ; bit 4, CB1 control, negative edge keyboard interrupt. ; bits 5-7, CB2 control, cassette output initially set high. ; IKIER EQU %11010000 ; Interrupt enable register control. ; bit 4, CB1 keyboard interrupt enable. ; bit 6, timer 1 interrupt enable. ; bit 7, set interrupts enabled. ; other enables not altered. ; PSTRB EQU %00000010 ; bit position in PCR of printer strobe, to toggle CA2 COPBIT EQU %00100000 ; bit position in PCR of cassette output, to toggle CB2 ; SWIOP EQU $3F ; Software interrupt used for breakpoints. ; BUFLEN EQU 81+1 ; Buffer up to 80 characters from keyboard. ; PROMPT EQU "*" ; Monitor prompt character. RUBCH EQU $7F ; Keyboard character that does rubout operation. BSPACE EQU $7F ; Character that backspaces VDU, also used to do rubout. LF EQU $0A ; Linefeed character. CR EQU $0D ; Carriage return character. SPACE EQU $20 ; Blank space character. COMMA EQU "," ; A comma character. MINUS EQU "-" ; A minus character. FFEED EQU $0C ; Character used as clear screen command. SEMIC EQU ";" ; A semicolon. ; IRQ EQU $10 ZERO EQU $04 ; ; Definitions of variables in page 3 ; ---------------------------------- ; BSS ; This data not saved to output file ORG $035B ISTACK EQU $ ; $035B - Stack pointer starts here. RTAB1 EQU $ ; $035B - RAM table 1 starts here. ; ; This table copied from ROM on start-up ; ; --- page 77 --- ; STACK RMB 2 ; $035B - Position of stack pointer when empty NTRACE RMB 2 ; $035D - Number of instructions to trace before stopping BSECHO RMB 1 ; $035F - Character sent to backspace display ECHOF RMB 1 ; $0360 - Keyboard buffer/echo control ; bits 0-5, don't care ; bit 6 echo console input to console output if set ; bit 7 buffer input lines, allow rubout if set ; PFLAG RMB 1 ; $0361 - Printer control flag, echo console output to printer if nonzero PNEW RMB 1 ; $0362 - This character not sent to printer. DELCNT RMB 2 ; $0363 - Non-zero delay count for cassette, controls baud rate. COPADR RMB 2 ; $0365 - Address for console output. CINADR RMB 2 ; $0367 - Address for console input. CASOPA RMB 2 ; $0369 - Address for cassette output. CASINA RMB 2 ; $036B - Address for cassette input. PRINT1 RMB 2 ; $036D - Address of printer output routine. FUNCTI RMB 2 ; $036F - Address of VDU function table. CMND1 RMB 2 ; $0371 - Address of monitor command table. IRQRTS RMB 2 ; $0373 - Address to go to on timer 1 interrupt. LINEPT RMB 2 ; $0375 - Address of memory input line, 0 if none. IRESV RMB 2 ; $0377 - Address of reserved vector routine. ISWI3 RMB 2 ; $0379 - Address of SWI1 routine. ISWI2 RMB 2 ; $037B - Address of SWI2 routine. IFIRQ RMB 2 ; $037D - Address of FIRQ routine. IIRQ RMB 2 ; $037F - Address of IRQ routine. ISWI RMB 2 ; $0381 - Address of SWI routine. INMI RMB 2 ; $0383 - Address of NMI routine. OFFSET RMB 2 ; $0385 - Cassette load offset ; ; General variables for monitor use ; HEADST RMB 2 ; $0387 - Static head pointer into line buffer HEADDY RMB 2 ; $0389 - Dynamic head pointer into line buffer TAIL RMB 2 ; $038B - Tail pointer into line buffer MSTACK RMB 2 ; $038D - stack saved whilst memory interpreting CROW RMB 1 ; $038F - current row of cursor on display CCOL RMB 1 ; $0390 - current column of cursor on display CPAGE RMB 2 ; $0391 - current start of display page in memory. MSAV RMB 2 ; $0393 - Saved address for memory command. GSAV RMB 2 ; $0395 - Saved address for go command. NAME RMB 6 ; $0397 - Saved name for cassette input output. CSSTRT RMB 2 ; $039D - Saved cassette output start address. CSEND RMB 2 ; $039F - Saved cassette output end address ONLINE RMB 1 ; $03A1 - flag set to zero when find or in input line. LASTC RMB 1 ; $03A2 - Saved last character from input line current. CBREAK RMB 2 ; $03A3 - Address of breakpoint, $FFFF if none NBREAK RMB 2 ; $03A5 - number of breakpoints to ignore before stopping user CINST RMB 1 ; $03A7 - user instruction at breakpoint address CTRACE RMB 2 ; $03A8 - number of instructions left to trace before stopping user. USRSTK RMB 2 ; $03AA - Saved user-stack pointer when user halted TEMP RMB 2 ; $03AC - Temporary storage BUFFER RMB BUFLEN ; $03AE - line input buffer ; ; $03FF - end of line input buffer ; ; I/O space ; --------- ; $0400 Video memory ; $0800 6845 CRTC ; $0900 ; $0980 6522 VIA ; REGA - b6-b0: printer output ; b7: printer busy input ; REGB - b6-b0: keyboard ASCII input ; b7: cassette input ; CA1 - input from printer acknowledge (not used) ; CA2 - output strobe to printer ; CB1 - input strobe from keyboard ; CB2 - output to cassette ; Timer1 - used to single step ; Timer2 - unused ; $0A00 8271 floppy disk controller ; ; ; Hardware reset starts at this address. ; CODE ; Code from here saved to output file ORG MPROM ; PUT $E000 ; RESET: LDA #MONDP ; Set up TFR A,DP ; direct page. SETDP MONDP ; Tell assembler. LDX #PTAB1 ; ROM table start. LDU #RTAB1 ; RAM table start. RST1: LDA ,X+ ; Copy ROM STA ,U+ ; to RAM CMPX #PTAB2 ; until end BNE RST1 ; of table. LDS STACK ; Set up stack pointer. LDX MPROM-2 CMPX #$A55A ; Check for extra ROM, BNE STRT1 ; not there, JSR [MPROM-4] ; else call it. STRT1: LDU #BACK ; Put monitor return PSHS U ; onto stack. LDD #12 ; Put dummy STRT2: PSHS A DECB ; registers BNE STRT2 ; onto stack. STS USRSTK ; Save stack pointer. LDX #BUFFER ; Get start of buffer STX HEADDY ; and set up pointers STX HEADST STX TAIL LBSR CRTCI ; Initialise CRT controller LBSR VIAI ; and VIA chips. CLR LASTC ; Set no saved character. LBSR BRKOUT ; Remove if exists LDX #$FFFF ; then set STX CBREAK ; non-existing. ; CLI ANDCC #$EF ; Allow interrupts. ; SETDP 0 MON: LDA #PROMPT ; Send prompt LDX LINEPT ; unless BNE MON1 ; memory input. LBSR CONOUT ; ; ---- page 78 ---- MON1: STA ONLINE ; Set no CR yet. PARSE: LDA #MONDP ; TFR A,DP ; SETDP MONDP ; Tell assembler LDX LINEPT ; See if mem input, BEQ PARSEC ; if so, LDA ,X ; then see if null yet BEQ MEND ; End if is null. PARSEC: BSR CONCHR ; Get input BEQ MON ; prompt on CR LDX CMND1 ; else command table LBSR DISPCH ; search. BRA PARSE ; ; ; Enter here for monitor to use memory input line ; (X) is start of line, ends with a null. ; multiple input lines are allowed, each line ends ; with carriage return. ; ; Exits with (a) zero if all ok, else (a) is $FF ; if found null too early, else (a) is character ; causing error. SETDP 0 ; MEMUSE: PSHS DP ; Save stack for return. STS MSTACK ; Save pointer in memory. STX LINEPT ; Set none saved CLR LASTC ; and call monitor. BRA MON ; CONCHR: LDA #CR ; Assume CR now TST ONLINE ; and if found CR then BEQ CON1 ; is correct. BSR CONIN ; Get input. CMPA #CR ; If not CR then BNE CON2 ; done. CON1: CLR ONLINE ; Set found CR CON2: RTS ; ; Console input routine, gets character from keyboard ; buffer or memory it finds null in memory then returns to ; to caller with error $FF. ; SETDP MONDP CONIN: PSHS DP,X LDA #MONDP ; Set up TFR A,DP ; direct page. LDA LASTC ; Saved one? BEQ CON5 ; none saved CLR LASTC ; not saved anymore PULS DP,X,PC ; CON5: LDX LINEPT ; see if mem input BEQ CON3 ; no, use buffer. LDA ,X+ ; Get men value BNE CON4 ; ok if not null. DECA ; Set to $FF MEND: LDS MSTACK ; clear mem CLR LINEPT+0 ; input CLR LINEPT+1 PULS DP,PC ; and return to caller. ; CON3: JSR [CINADR] ; Get console input CON4: STX LINEPT ; store new mem pointer PULS DP,X,PC ; ; This routine prints the registers from the stack as pointed ; to by usrstk, then prints usrstk itself. ; also prints 5 bytes starting at (PC). ; EXREG: LDX #TITLES ; Headings BSR STRING ; printed first LDU USRSTK ; LDB #$04 ; ie, CC,A,B,DP. EX1: LDA ,U+ ; Get data LBSR OPARSP ; output as 2 hex digits DECB ; BNE EX1 ; until all 4 output LDB #$04 ; ie, X, Y, U, PC ; EX2: LDX ,U++ ; get 2 bytes LBSR OPXREG ; as 4 hex digits DECB ; BNE EX2 ; until all output LDX