Keyboard Input Routines
and Character Coded Output
on the 6809
Again, be sure, you've read through, assembled, and tested
the 6801 code, and understand the program and where the 6801's extensions are being
used.
* simple 8-bit hexadecimal output for 6809
* using parameter stack,
* with test frame
* Joel Matthew Rees, October 2024
*
OPT 6809
INCLUDE rt_rig03_6809.asm
****************
* Program code:
*
* Essential monitor ROM parameters
* ECHO suppress -- set non-zero before each call to XINCH/XINCHN
* to suppress echo for that call only.
* Not the same address as 6800 EXBUG.
AECHO EQU $FF58 ; ECHO suppress per-call
*
* Essential monitor ROM routines
XINCH EQU $F012 ; wait for key, return in A, preserves B, X, see AECHO
*
* Wait for input, return character
* Call INCHNE for no echo.
INCHNE INC AECHO ; XINCH always clears it.
INCHAR BSR INCHV
TFR A,B
CLRA
PSHU D
RTS
*
INCHV JMP XINCH ; returns with character in A
*
*
PROMPT FCB CR,LF ; Put message at beginning of line
FCC "Type any key, Q to quit. " ;
FCB CR,LF ; Put the prompt on a new line
FCB NUL
KEYCOL FCC "KEY:"
FCB NUL
COLBIN FCB ASCCOL,NUL
COLHEX FCC ": $"
FCB NUL
*
*
*
PGSTRT LEAX PROMPT,PCR
PSHU X
LBSR OUTS
LBSR INCHNE ; Hold off echo
LDD ,U
PSHU D
LEAX KEYCOL,PCR
PSHU X
LBSR OUTS
LBSR OUTC ; output character
LDD ,U
PSHU D
LEAX COLBIN,PCR
PSHU X
LBSR OUTS
LBSR OUTB8
LDD ,U
PSHU D
LEAX COLHEX,PCR
PSHU X
LBSR OUTS
LBSR OUTHX8
LBSR OUTNWLN
PULU D ; balance stack
CMPB #ASCQ
BNE PGSTRT
RTS
*
END ENTRY
Again, the keyboard input routine has two entry points, with and without echo.
But there is no PDUP, because it is assumed that the cost of the call is close enough to the cost of the LDD ,U/PSHU D pair that it composes to be worth it, and you often would not be doing that anyway.
The 6809's low level is pretty high.
Again, I hope you'll compare the 6809 code here with
the 6801 code and take note of how the 6809 makes it easier to express the algorithm with fewer calls to subroutines.
* A simple run-time framework inclusion for 6809
* providing parameter stack and local base
* Version 00.00.03
* Joel Matthew Rees, October 2024
*
* Essential control codes
LF EQU $0A ; line feed
CR EQU $0D ; carriage return
NUL EQU 0
*
* Other essential ASCII codes
ASC0 EQU '0 ; Some assemblers won't handle 'c constants well.
ASC9 EQU '9
ASCA EQU 'A
ASCXGAP EQU ASCA-ASC9-1 ; Gap between '9' and 'A' for hexadecimal
ASCCOL EQU ':
ASCQ EQU 'Q
*
NATWID EQU 2 ; 2 bytes in the CPU's natural integer
*
*
ORG $2000 ; MDOS says this is a good place for usr stuff
SETDP $20 ; some other assemblers
* SETDP $2000 ; EXORsim
LOCBAS EQU * ; here pointer, local static base starts here.
ENTRY JMP START
NOP
SSAVE RMB 2 ; a place to keep S so we can return clean
DPSAVE RMB 2 ; a place to keep DP so we can return clean
* room for something
* Not much here
*
SETDP 0 ; Not yet set up
ORG $2100 ; Give the DP room.
RMB 2 ; a little bumper space
SSTKLIM RMB 32 ; 16 levels of call, max
* ; 6809 is pre-dec (pre-store-decrement) push
SSTKBAS RMB 2 ; a little bumper space
PSTKLIM RMB 64 ; 16 levels of call at two parameters per call
PSTKBAS RMB 2 ; bumper space -- parameter stack is pre-dec
*
*
INITRT TFR DP,A
CLRB
TFR D,Y ; save old DP base for a moment
LEAX LOCBAS,PCR ; Set up new DP base
TFR X,D
TFR A,DP ; Now we can access DP variables correctly.
SETDP $20 ; some other assemblers
* SETDP $2000 ; EXORsim
STY <DPSAVE ; technically only need to save high byte
LEAU PSTKBAS,PCR ; Set up the parameter stack
PULS X ; get return address
STS <SSAVE ; Save what the monitor gave us.
LEAS SSTKBAS,PCR ; Move to our own stack
JMP ,X ; return via X
*
*
* No need for PPOPD, PPUSHD, PPOPX, or PPUSHX, etc. in 6809 code.
*
*
* Essential monitor ROM routines
XOUTCH EQU $F018 ; output ACCM A to debug terminal, preserves others
*
* Output an 8-bit byte in hexadecimal,
* byte as a 16-bit parameter on PSP.
OUTHX8 LDB 1,U ; get the byte
LSRB
LSRB
LSRB
LSRB
BSR OUTRAD
LDB 1,U
ANDB #$0F ; mask it off
BSR OUTRAD
LEAU NATWID,U
RTS
*
* Convert the value in B to ASCII numeric,
* including hexadecimals and up to base 36 ('Z'+1)
OUTRAD ADDB #ASC0 ; Add the ASCII for '0'
CMPB #ASC9 ; Greater than '9'?
BLS OUTRADD ; no, output as is.
ADDB #ASCXGAP ; Adjust it to 'A' to 'Z'
OUTRADD CLRA
STD ,--U
LBSR OUTC
RTS
*
* Output the 8-bit binary (base two) number on the stack.
* For consistency, we are passing the byte in the low-order byte
* of a 16-bit word.
OUTB8 LDB #8 ; 8 bits
OUTB8L LSL 1,U ; Get the leftmost bit of the lower byte.
BCS OUTB81
OUTB80 LDA #'0
BRA OUTB8B
OUTB81 LDA #'1
OUTB8B JSR OUTCV
DECB
BNE OUTB8L ; loop if not Zero
LEAU NATWID,U ; drop parameter bytes
RTS
*
OUTNWLN LDA #CR ; driver level code to output a new line
BSR OUTCV
LDA #LF
BSR OUTCV
RTS
*
* We can handle the parameter stack directly.
* Preserves B and others
OUTC LDA 1,U ; Get the character in A where XOUTCH wants it.
LEAU NATWID,U ; Got it in A, now drop it from the stack.
BSR OUTCV ; output via monitor ROM
RTS
*
* Preserves B, X, Y, U
OUTCV JMP XOUTCH ; driver code for outputting a character
*
* And we can handle the parameter stack directly here, too.
OUTS PULU X ; get the string pointer
OUTSL LDA ,X+ ; get the byte, update the pointer
BEQ OUTDN ; if NUL, leave
BSR OUTCV ; use the same call OUTC uses.
BRA OUTSL ; next character
OUTDN RTS
*
*
******************************
* intermediate-level library:
*
* We often will not need these, but we'll go ahead and define them:
*
* input parameters:
* 16-bit left, right
* output parameter:
* 16-bit sum
ADD16 LDD NATWID,U ; left
ADDD ,U++ ; right
STD ,U ; sum (N, Z, & C flags should be correct)
RTS
* Flags: Specifically,
* N and Z get set correctly by the final store double;
* C should make it through manipulating X and storing D.
* V gets cleared.
*
* input parameters:
* 16-bit left, right
* output parameter:
* 16-bit difference
SUB16 LDD NATWID,U ; left
SUBD ,U++ ; right
STD ,U ; difference (N, Z, & C flags should be correct)
RTS
* Flags: Specifically,
* N and Z get set correctly by the final store double;
* C should make it through manipulating X and storing D.
* V gets cleared.
*
*
************************************
* Start run-time, call program.
* Expects program to define PGSTRT:
*
START LBSR INITRT
*
LBSR PGSTRT
*
DONE LDS <SSAVE ; restore the monitor stack pointer
LDD <DPSAVE ; restore the monitor DP
TFR A,DP
SETDP 0 ; For lack of a better way to set it.
NOP ; remember to set a breakpoint here!
NOP ; landing pad
NOP
NOP
JMP [$FFFE] ; alternatively, jmp through reset vector
*
* Anyway, if running in EXORsim,
* Ctrl-C should bring you back to EXORsim monitor,
* but not necessarily to your program in a runnable state.
Save, assemble with lwasm, paste the srecord object at the load command, play with it.
Don't forget to remove the S0 and S5 records before you paste it in.
Compare it with the 6801 source.
For reference, here's the srecord object, with the S0 and S5 records deleted:
S10720007E21E41243
S10D21661FB85F1F02308DFE911FA9
S1132170101F8B109F06338CEB351010DF04328C4C
S1132180A16E84E641545454548D09E641C40F8D24
S113219003334239CB30C1392302CB074FEDC31788
S11321A0001F39C60868412504863020028631BDE7
S11321B021C85A26F0334239860D8D0C860A8D08C3
S11321C039A64133428D01397EF0183710A6802795
S11321D0048DF520F839EC42E3C1EDC439EC42A397
S11321E0C1EDC43917FF7F17004610DE04DC061F5B
S11321F08B121212126E9FFFFE7CFF588D061F89F0
S11322004F3606397EF0120D0A5479706520616EDE
S113221079206B65792C205120746F207175697455
S11322202E200D0A004B45593A003A003A2024006A
S1132230308CD4361017FF9317FFBEECC43606302B
S11322408CE3361017FF8417FF77ECC43606308C06
S1132250D9361017FF7517FF4AECC43606308CCCFC
S1132260361017FF6617FF1B17FF4D3706C151269F
S1052270BF3970
S9032000DC
See what the capabilities of the 6809 inspires you to do.
And, to the 68000!
debug session?!?!?!?
Yeah. Need to fix those bugs.
No comments:
Post a Comment