I thought I’d share some of the cool features I’ve discovered over the years using LWASM that I don’t think are widely known or maybe I just live under a rock. 🙂
One of the best things are the need for less labels when writing your code. You can use the less than (<) and greater than (>) as labels that direct the code to the exclamation mark (!) in your code. For example:
Cool program #1 with labels:
LDX #$1000 LOOP1: INC ,X+ CMPX #$2000 BNE LOOP1 LDD ,Y BNE Done LDD #$BBBB Done: RTS
Cool program #1 with <, > and ! – Look ma, no labels:
LDX #$1000 ! INC ,X+ CMPX #$2000 BNE < LDD ,Y BNE > LDD #$BBBB ! RTS
Another cool label shortcut/feature is the use of @ at the end of your labels. You can re-use labels in the same source code as long as you leave a blank line between code sections and use an @ at the end. I haven’t used this too much myself but I have seen it used in a few 6809 source code files I’ve come across. It works like this
Cool program #2 with all different labels:
LDX #$1000 Loop1 INC ,X+ CMPX #$2000 BNE Loop1 CMPD #$AAAA BNE Skip1 LDD #$BBBB Skip1: BRA NextCode RTS NextCode: LDX #$5000 Loop2 INC ,X+ CMPX #$6000 BNE Loop2 RTS
If you leave a blank line after the RTS and put @ at the end of your label names you can reuse the same labels in the next section (see the 1@):
LDX #$1000 1@ INC ,X+ CMPX #$2000 BNE 1@ CMPD #$AAAA BNE 2@ LDD #$BBBB 2@ BRA NextCode RTS NextCode: LDX #$5000 1@ INC ,X+ CMPX #$6000 BNE 1@ RTS
Another cool thing LWASM can do is tell you the CPU cycle counts of your code. You can insert the following anywhere in your code that you’d like to count the cycles. Leave a few spaces on a line then type
opt c * enable cycle counts opt cd * enable detailed cycle counts breaking down addressing modes opt ct * show a running subtotal of cycles opt cc * clear the running subtotal
As the comments show the c shows the cycle counts, the ct tells the assembler to add the counts and the cc clears the current count. You can use any of these individually or together as I have.
opt c,ct,cc * show cycle count, add the counts, clear the current count
When you look at the output listing LWASM writes when it assembles your program you will see the cycles
Mem Code Cycles Assembly Code (Mnemonics) 4000 8E2000 [3] LDX #$2000 4003 A684 [4+0] LDA ,X 4005 A61F [4+1] LDA -1,X 4009 A610 [4+1] LDA -16,X 400B A688EF [4+1] LDA -17,X 400E A68880 [4+1] LDA -128,X 4011 A689FF7F [4+4] LDA -129,X 4015 A601 [4+1] LDA 1,X 4017 A60F [4+1] LDA 15,X 4019 A68810 [4+1] LDA 16,X 401C A6887F [4+1] LDA 127,X 401F A6890080 [4+4] LDA 128,X
Another cool feature is Conditional Assembly. Conditional assembly basically uses IF, ELSE and END in your code and depending on the setting that you define then LWASM will assemble the code one way or another. There are many different conditions show in the LWASM documentation here. Just remember to use some spaces on the lines that you have your IF, ELSE, END or whatever other DEFINE you are using.
One last thing I sometimes use are Pragmas. You use them again with some spaces on the line then the word pragma a few spaces then the pragma itself. For example if I don’t want to see all the output in the assembly listing I use these pragmas:
pragma nolist * The code below will not be shown in the listing INCLUDE ./includes/CoCo3_Start.asm INCLUDE ./includes/Def_CoCo3_Memory_Description_and_Defines.asm pragma list * The code below will be shown in the listing
In the example above, everything still gets assembled as normal but the output of sections will be hidden in the listing. Useful if you have tons of code you don’t need to look through. Here’s the list of pragmas available.
There’s much more the LWASM program can do like macros and more. Of course the documentation is available here.
Have fun,
Glen
I started reading this thinking I could follow along? Mistake! In a couple of your descriptions of the interesting usage you mentioned some “why” where you could re-use labels. OK I can see that where you might have some fairly simple and repetitive routines which are fast and not quite worth making into a subroutine. But the other examples just left me with “huh?” Maybe I need to be more awake and re-read. 🙂
HI Glen,
first, thank you for sharing the tips for 6809 assembly, I just read the “Optimizing 6809 Assembly Code”, four parts in a row!
For me, I did learn a lot on 6809 code optimizing by reading the ASSIST09 source code, and use it on a personal project about 30 years ago… More learning by dissambling the P/L9 compiled code analyzing, then rewriting (most of the LDA #0 could be an CLRA, while no CCR register needed).
Today I’m trying a new 6809 project, using an HD6309, and will re-assemble the ASSIST09 monitor using the Hitachi 6309 instructions.
There the problems starting with LWASM!
Even using the latest version, LWASM stop assembling the ASSIST09 source code in the definition of the WORKPG definition: the label VECTAB defined as ” * – NUMVTR*2 ” stop the assembly, while it can be defined on the first pass!
LWASM seems to be a great piece of soft, but with the lack of trying more than one pass to define the labels, it’s not that useful, at least for ASSIST09 (relocatable monitor).
This isn’t an issue on the asm6809, that product 6309 code too.
asm6809 is there: https://www.6809.org.uk/asm6809/
Have a nice code assembling day!
-=chf=-
Hi chf,
I’m glad you found my blog useful, it always makes me happy to know others find it useful. You definitely can learn a lot of neat tricks by disassembling other peoples source code. As for your LWASM problem, make sure there are no spaces in you equation, otherwise LWASM will think that part of it is a comment. If you post the part of the ASSIST09 source could that has the problem I could take a look at it and see if I can offer any help.
Cheers,
Glen
Hi Glen,
thank for your fast reply, on this Sunday! ;o)
So, after your suggestion, I double check anythings…
First, I did run the 4.17 version of lwasm, move to the 4.18 version but same issues
Re-read the manual, I think that the ‘ * ‘ was not seen as the ‘ PC ‘ during assembly, but it seems to be OK.
I make the source smaller, if you want to test it. I can upload to my “website” the full source, that assemble great with asm6809, but had issues with the assist09. I would prefer that lwasm as the only tool I would use, but after trying, I give up, coz I could assemble it on an other way.
At the moment, I’m on the hardware design, and playing with KiCad…
Here the source I work on (part of it):
;TTL ASSIST09 – MC6809 MONITOR
;OPT ABS,LLE=85,S,CRE
;OPT PAG ;opt cd – enable detailed cycle counts breaking down addressing modes: [5+3]
*pragma 6309conv,m80ext ;index0tonone autobranchlength
; *************************************
; * COPYRIGHT (C) MOTOROLA, INC. 1979 *
; *************************************
; *********************************************
; * GLOBAL MODULE EQUATES
; *********************************************
I_O_SEL EQU $EF ;base I/O selected on uP card
I_O_PAG EQU I_O_SEL*$100 ;base I/O adresses
I_O_SIZ EQU 256 ;lenght of I/O page
ROMBEG EQU I_O_PAG+I_O_SIZ ; ROM START ASSEMBLY ADDRESS $F000
RAMOFS EQU -I_O_SIZ-$200 ; ROM OFFSET TO RAM WORK PAGE -$300
ROMSIZ EQU $10000-ROMBEG ; ROM SIZE $1000
ROM2OF EQU ROMBEG+$0800 ; START OF EXTENSION ROM $F800
ACIA EQU I_O_PAG+$00 ; DEFAULT ACIA ADDRESS $EF00
PTM EQU I_O_PAG+$08 ; DEFAULT PTM ADDRESS $EF08
DFTCHP EQU 0 ; DEFAULT CHARACTER PAD COUNT
DFTNLP EQU 5 ; DEFAULT NEW LINE PAD COUNT
PROMPT EQU ‘>’ ; PROMPT CHARACTER
NUMBKP EQU 8 ; NUMBER OF BREAKPOINTS
; *********************************************
; *********************************************
; * MISCELLANEOUS EQUATES
; *********************************************
EOT EQU $04 ; END OF TRANSMISSION
BELL EQU $07 ; BELL CHARACTER
LF EQU $0A ; LINE FEED
CR EQU $0D ; CARRIAGE RETURN
DLE EQU $10 ; DATA LINE ESCAPE
CAN EQU $18 ; CANCEL (CTRL-X)
; * PTM ACCESS DEFINITIONS
PTMSTA EQU PTM+1 ; READ STATUS REGISTER
PTMC13 EQU PTM ; CONTROL REGISTER 1 AND 3
PTMC2 EQU PTM+1 ; CONTROL REGISTER 2
PTMTM1 EQU PTM+2 ; LATCH 1
PTMTM2 EQU PTM+4 ; LATCH 2
PTMTM3 EQU PTM+6 ; LATCH 3
; * ACIA ACCESS DEFINITIONS
ACIACR EQU ACIA+0 ;command register offset
ACIASR EQU ACIA+0 ;status register offset
ACIATD EQU ACIA+1 ;transmit data register offset
ACIADR EQU ACIA+1 ;receive data register offset
SKIP2 EQU $8C ; “CMPX #” OPCODE – SKIPS TWO BYTES
; **************************************************
; * ASSIST09 MONITOR SWI FUNCTIONS
; * THE FOLLOWING EQUATES DEFINE FUNCTIONS PROVIDED
; * BY THE ASSIST09 MONITOR VIA THE SWI INSTRUCTION.
; **************************************************
INCHNP EQU 0 ; INPUT CHAR IN A REG – NO PARITY
OUTCH EQU 1 ; OUTPUT CHAR FROM A REG
PDATA1 EQU 2 ; OUTPUT STRING
PDATA EQU 3 ; OUTPUT CR/LF THEN STRING
OUT2HS EQU 4 ; OUTPUT TWO HEX AND SPACE
OUT4HS EQU 5 ; OUTPUT FOUR HEX AND SPACE
PCRLF EQU 6 ; OUTPUT CR/LF
SPACE EQU 7 ; OUTPUT A SPACE
MONITR EQU 8 ; ENTER ASSIST09 MONITOR
VCTRSW EQU 9 ; VECTOR EXAMINE/SWITCH
BRKPT EQU 10 ; USER PROGRAM BREAKPOINT
PAUSE EQU 11 ; TASK PAUSE FUNCTION
NUMFUN EQU 11 ; NUMBER OF AVAILABLE FUNCTIONS
; * NEXT SUB-CODES FOR ACCESSING THE VECTOR TABLE.
; * THEY ARE EQUIVALENT TO OFFSETS IN THE TABLE.
; * RELATIVE POSITIONING MUST ME MAINTAINED.
_AVTBL EQU 0 ; ADDRESS OF VECTOR TABLE
_CMDL1 EQU 2 ; FIRST COMMAND LIST
_RSVD EQU 4 ; RESERVED HARDWARE VECTOR
_SWI3 EQU 6 ; SWI3 ROUTINE
_SWI2 EQU 8 ; SWI2 ROUTINE
_FIRQ EQU 10 ; FIRQ ROUTINE
_IRQ EQU 12 ; IRQ ROUTINE
_SWI EQU 14 ; SWI ROUTINE
_NMI EQU 16 ; NMI ROUTINE
_RESET EQU 18 ; RESET ROUTINE
_CION EQU 20 ; CONSOLE ON
_CIDTA EQU 22 ; CONSOLE INPUT DATA
_CIOFF EQU 24 ; CONSOLE INPUT OFF
_COON EQU 26 ; CONSOLE OUTPUT ON
_CODTA EQU 28 ; CONSOLE OUTPUT DATA
_COOFF EQU 30 ; CONSOLE OUTPUT OFF
_HSDTA EQU 32 ; HIGH SPEED PRINTDATA
_BSON EQU 34 ; PUNCH/LOAD ON
_BSDAT EQU 36 ; PUNCH/LOAD DATA
_BSOFF EQU 38 ; PUNCH/LOAD OFF
_PAUSE EQU 40 ; TASK PAUSE ROUTINE
_EXPAN EQU 42 ; EXPRESSION ANALYZER
_CMDL2 EQU 44 ; SECOND COMMAND LIST
_ACIA EQU 46 ; ACIA ADDRESS
_PAD EQU 48 ; CHARACTER PAD AND NEW LINE PAD
_ECHO EQU 50 ; ECHO/LOAD AND NULL BKPT FLAG
_PTM EQU 52 ; PTM ADDRESS
NUMVTR EQU 52/2+1 ; NUMBER OF VECTORS
HIVTR EQU 52 ; HIGHEST VECTOR OFFSET
; **************************************************
; * WORK AREA
; * THIS WORK AREA IS ASSIGNED TO THE PAGE ADDRESSED BY
; * -$1800,PCR FROM THE BASE ADDRESS OF THE ASSIST09
; * ROM. THE DIRECT PAGE REGISTER DURING MOST ROUTINE
; * OPERATIONS WILL POINT TO THIS WORK AREA. THE STACK
; * INITIALLY STARTS UNDER THE RESERVED WORK AREAS AS
; * DEFINED HEREIN.
; **************************************************
WORKPG EQU ROMBEG+RAMOFS ; SETUP DIRECT PAGE ADDRESS $ED00
SETDP WORKPG/$100 ; NOTIFY ASSEMBLER $ED
ORG WORKPG+256 ; READY PAGE DEFINITIONS $EE00
; * THE FOLLOWING THRU BKPTOP MUST RESIDE IN THIS ORDER
; * FOR PROPER INITIALIZATION
ORG *-4
PAUSER EQU * ; PAUSE ROUTINE
ORG *-1
SWIBFL EQU * ; BYPASS SWI AS BREAKPOINT FLAG
ORG *-1
BKPTCT EQU * ; BREAKPOINT COUNT
ORG *-2
SLEVEL EQU * ; STACK TRACE LEVEL
ORG *-NUMVTR*2
VECTAB EQU * ; VECTOR TABLE
ORG *-2*NUMBKP
BKPTBL EQU * ; BREAKPOINT TABLE
ORG *-2*NUMBKP
BKPTOP EQU * ; BREAKPOINT OPCODE TABLE
ORG *-2
WINDOW EQU * ; WINDOW
ORG *-2
ADDR EQU * ; ADDRESS POINTER VALUE
ORG *-1
BASEPG EQU * ; BASE PAGE VALUE
ORG *-2
NUMBER EQU * ; BINARY BUILD AREA
ORG *-2
LASTOP EQU * ; LAST OPCODE TRACED
ORG *-2
RSTACK EQU * ; RESET STACK POINTER
ORG *-2
PSTACK EQU * ; COMMAND RECOVERY STACK
ORG *-2
PCNTER EQU * ; LAST PROGRAM COUNTER
ORG *-2
TRACEC EQU * ; TRACE COUNT
ORG *-1
SWICNT EQU * ; TRACE “SWI” NEST LEVEL COUNT
ORG *-1 ; (MISFLG MUST FOLLOW SWICNT)
MISFLG EQU * ; LOAD CMD/THRU BREAKPOINT FLAG
ORG *-1
DELIM EQU * ; EXPRESSION DELIMITER/WORK BYTE
ORG *-40
ROM2WK EQU * ; EXTENSION ROM RESERVED AREA
ORG *-21 ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<< for 6309 add two more byte: -23
TSTACK EQU * ; TEMPORARY STACK HOLD
STACK EQU * ; START OF INITIAL STACK
; *****************************************************
; * DEFAULT THE ROM BEGINNING ADDRESS TO 'ROMBEG'
; * ASSIST09 IS POSITION ADDRESS INDEPENDENT HOWEVER
; * WE ASSEMBLE ASSUMING CONTROL OF THE HARDWARE VECTORS.
; * NOTE THAT THE WORK RAM PAGE MUST BE 'RAMOFS'
; * FROM THE ROM BEGINNING ADDRESS.
; *****************************************************
ORG ROMBEG+$800 ; ROM ASSEMBLY/DEFAULT ADDRESS <<<<<VALID STACK RAM
; * OUTPUT: U->VECTOR TABLE ADDRESS
; * DPR->ASSIST09 WORK AREA PAGE
; * THE VECTOR TABLE AND DEFAULTS ARE INITIALIZED
; * ALL REGISTERS VOLATILE.
; *****************************************************
BLDVTR LEAX VECTAB,PCR ; ADDRESS VECTOR TABLE
TFR X,D ; OBTAIN BASE PAGE ADDRESS
TFR A,DP ; SETUP DPR
STA BASEPG ; STORE FOR QUICK REFERENCE
LEAU ,X ; RETURN TABLE TO CALLER
LEAY <INITVT,PCR ; LOAD FROM ADDR
STU ,X++ ; INIT VECTOR TABLE ADDRESS
LDB #NUMVTR-5 ; NUMBER OF RELOCATABLE VECTORS
PSHS B ; STORE INDEX ON STACK
BLD2 TFR Y,D ; PREPARE ADDRESS RESOLVE
ADDD ,Y++ ; TO ABSOLUTE ADDRESS
STD ,X++ ; INTO VECTOR TABLE
DEC ,S ; COUNT DOWN
BNE BLD2 ; BRANCH IF MORE TO INSERT
LDW #INTVE-INTVS ;<<<< HD6309
TFM Y+,X+ ;<<<< HD6309
LEAY ROM2OF,PCR ; TEST POSSIBLE EXTENSION ROM
LDX #$20FE ; LOAD "BRA *" FLAG PATTERN
CMPX ,Y++ ; ? EXTENDED ROM HERE
BNE BLDRTN ; BRANCH NOT OUR ROM TO RETURN
JSR ,Y ; CALL EXTENDED ROM INITIALIZE
BLDRTN PULS B,PC ; RETURN TO INITIALIZER
; *****************************************************
; * RESET ENTRY POINT
; * HARDWARE RESET ENTERS HERE IF ASSIST09 IS ENABLED
; * TO RECEIVE THE MC6809 HARDWARE VECTORS. WE CALL
; * THE BLDVTR SUBROUTINE TO INITIALIZE THE VECTOR
; * TABLE, STACK, AND THE FIREUP THE MONITOR VIA SWI
; * CALL.
; *****************************************************
RESET LEAS STACK,PCR ; SETUP INITIAL STACK
BSR BLDVTR ; BUILD VECTOR TABLE
RESET2 CLRA ; ISSUE STARTUP MESSAGE
TFR A,DP ; DEFAULT TO PAGE ZERO
SWI ; PERFORM MONITOR FIREUP
FCB MONITR ; TO ENTER COMMAND PROCESSION
BRA RESET2 ; REENTER MONITOR IF 'CONTINUE'
; *****************************************************
; * INITVT – INITIAL VECTOR TABLE
; * THIS TABLE IS RELOCATED TO RAM AND REPRESENTS THE
; * INITIAL STATE OF THE VECTOR TABLE. ALL ADDRESSES
; * ARE CONVERTED TO ABSOLUTE FORM. THIS TABLE STARTS
; * WITH THE SECOND ENTRY, ENDS WITH STATIC CONSTANT
; * INITIALIZATION DATA WHICH CARRIES BEYOND THE TABLE.
; *****************************************************
INITVT FDB CMDTBL-* ; DEFAULT FIRST COMMAND TABLE
FDB RSRVDR-* ; DEFAULT UNDEFINED HARDWARE VECTOR
FDB SWI3R-* ; DEFAULT SWI3
FDB SWI2R-* ; DEFAULT SWI2
FDB FIRQR-* ; DEFAULT FIRQ
FDB IRQR-* ; DEFAULT IRQ ROUTINE
FDB SWIR-* ; DEFAULT SWI ROUTINE
FDB NMIR-* ; DEFAULT NMI ROUTINE
FDB RESET-* ; RESTART VECTOR
FDB CION-* ; DEFAULT CION
FDB CIDAT-* ; DEFAULT CIDAT
FDB CIOFF-* ; DEFAULT CIOFF
FDB COON-* ; DEFAULT COON
FDB CODAT-* ; DEFAULT CODAT
FDB COOFF-* ; DEFAULT COOFF
FDB HSDTA-* ; DEFAULT HSDTA
FDB BSON-* ; DEFAULT BSON
FDB BSDAT-* ; DEFAULT BSDAT
FDB BSOFF-* ; DEFAULT BSOFF
FDB PAUSER-* ; DEFAULT PAUSE ROUTINE
FDB EXP1-* ; DEFAULT EXPRESSION ANALYZER
FDB CMDTB2-* ; DEFAULT SECOND COMMAND TABLE
; * CONSTANTS
INTVS FDB ACIA ; DEFAULT ACIA
FCB DFTCHP,DFTNLP ; DEFAULT NULL PADDS
FDB 0 ; DEFAULT ECHO
FDB PTM ; DEFAULT PTM
FDB 0 ; INITIAL STACK TRACE LEVEL
FCB 0 ; INITIAL BREAKPOINT COUNT
FCB 0 ; SWI BREAKPOINT LEVEL
FCB $39 ; DEFAULT PAUSE ROUTINE (RTS)
INTVE EQU *
CMDTBL equ *
RSRVDR equ *
SWI3R equ *
SWI2R equ *
FIRQR equ *
IRQR equ *
SWIR equ *
NMIR equ *
CION equ *
CIDAT equ *
CIOFF equ *
COON equ *
CODAT equ *
COOFF equ *
HSDTA equ *
BSON equ *
BSDAT equ *
BSOFF equ *
EXP1 equ *
CMDTB2 equ *
Hi chf,
I got it to assemble by assigning names instead of the ‘*’ in all the pointers. I don’t know if it’s correct (I think it is), but give it a try and compare the binary with the one that asm09 made.
;TTL ASSIST09 – MC6809 MONITOR
;OPT ABS,LLE=85,S,CRE
;OPT PAG ;opt cd – enable detailed cycle counts breaking down addressing modes: [5+3]
*pragma 6309conv,m80ext ;index0tonone autobranchlength
; *************************************
; * COPYRIGHT (C) MOTOROLA, INC. 1979 *
; *************************************
; *********************************************
; * GLOBAL MODULE EQUATES
; *********************************************
I_O_SEL EQU $EF ;base I/O selected on uP card
I_O_PAG EQU I_O_SEL*$100 ;base I/O adresses
I_O_SIZ EQU 256 ;lenght of I/O page
ROMBEG EQU I_O_PAG+I_O_SIZ ; ROM START ASSEMBLY ADDRESS $F000
RAMOFS EQU -I_O_SIZ-$200 ; ROM OFFSET TO RAM WORK PAGE -$300
ROMSIZ EQU $10000-ROMBEG ; ROM SIZE $1000
ROM2OF EQU ROMBEG+$0800 ; START OF EXTENSION ROM $F800
ACIA EQU I_O_PAG+$00 ; DEFAULT ACIA ADDRESS $EF00
PTM EQU I_O_PAG+$08 ; DEFAULT PTM ADDRESS $EF08
DFTCHP EQU 0 ; DEFAULT CHARACTER PAD COUNT
DFTNLP EQU 5 ; DEFAULT NEW LINE PAD COUNT
PROMPT EQU ‘>’ ; PROMPT CHARACTER
NUMBKP EQU 8 ; NUMBER OF BREAKPOINTS
; *********************************************
; *********************************************
; * MISCELLANEOUS EQUATES
; *********************************************
EOT EQU $04 ; END OF TRANSMISSION
BELL EQU $07 ; BELL CHARACTER
LF EQU $0A ; LINE FEED
CR EQU $0D ; CARRIAGE RETURN
DLE EQU $10 ; DATA LINE ESCAPE
CAN EQU $18 ; CANCEL (CTRL-X)
; * PTM ACCESS DEFINITIONS
PTMSTA EQU PTM+1 ; READ STATUS REGISTER
PTMC13 EQU PTM ; CONTROL REGISTER 1 AND 3
PTMC2 EQU PTM+1 ; CONTROL REGISTER 2
PTMTM1 EQU PTM+2 ; LATCH 1
PTMTM2 EQU PTM+4 ; LATCH 2
PTMTM3 EQU PTM+6 ; LATCH 3
; * ACIA ACCESS DEFINITIONS
ACIACR EQU ACIA+0 ;command register offset
ACIASR EQU ACIA+0 ;status register offset
ACIATD EQU ACIA+1 ;transmit data register offset
ACIADR EQU ACIA+1 ;receive data register offset
SKIP2 EQU $8C ; “CMPX #” OPCODE – SKIPS TWO BYTES
; **************************************************
; * ASSIST09 MONITOR SWI FUNCTIONS
; * THE FOLLOWING EQUATES DEFINE FUNCTIONS PROVIDED
; * BY THE ASSIST09 MONITOR VIA THE SWI INSTRUCTION.
; **************************************************
INCHNP EQU 0 ; INPUT CHAR IN A REG – NO PARITY
OUTCH EQU 1 ; OUTPUT CHAR FROM A REG
PDATA1 EQU 2 ; OUTPUT STRING
PDATA EQU 3 ; OUTPUT CR/LF THEN STRING
OUT2HS EQU 4 ; OUTPUT TWO HEX AND SPACE
OUT4HS EQU 5 ; OUTPUT FOUR HEX AND SPACE
PCRLF EQU 6 ; OUTPUT CR/LF
SPACE EQU 7 ; OUTPUT A SPACE
MONITR EQU 8 ; ENTER ASSIST09 MONITOR
VCTRSW EQU 9 ; VECTOR EXAMINE/SWITCH
BRKPT EQU 10 ; USER PROGRAM BREAKPOINT
PAUSE EQU 11 ; TASK PAUSE FUNCTION
NUMFUN EQU 11 ; NUMBER OF AVAILABLE FUNCTIONS
; * NEXT SUB-CODES FOR ACCESSING THE VECTOR TABLE.
; * THEY ARE EQUIVALENT TO OFFSETS IN THE TABLE.
; * RELATIVE POSITIONING MUST ME MAINTAINED.
_AVTBL EQU 0 ; ADDRESS OF VECTOR TABLE
_CMDL1 EQU 2 ; FIRST COMMAND LIST
_RSVD EQU 4 ; RESERVED HARDWARE VECTOR
_SWI3 EQU 6 ; SWI3 ROUTINE
_SWI2 EQU 8 ; SWI2 ROUTINE
_FIRQ EQU 10 ; FIRQ ROUTINE
_IRQ EQU 12 ; IRQ ROUTINE
_SWI EQU 14 ; SWI ROUTINE
_NMI EQU 16 ; NMI ROUTINE
_RESET EQU 18 ; RESET ROUTINE
_CION EQU 20 ; CONSOLE ON
_CIDTA EQU 22 ; CONSOLE INPUT DATA
_CIOFF EQU 24 ; CONSOLE INPUT OFF
_COON EQU 26 ; CONSOLE OUTPUT ON
_CODTA EQU 28 ; CONSOLE OUTPUT DATA
_COOFF EQU 30 ; CONSOLE OUTPUT OFF
_HSDTA EQU 32 ; HIGH SPEED PRINTDATA
_BSON EQU 34 ; PUNCH/LOAD ON
_BSDAT EQU 36 ; PUNCH/LOAD DATA
_BSOFF EQU 38 ; PUNCH/LOAD OFF
_PAUSE EQU 40 ; TASK PAUSE ROUTINE
_EXPAN EQU 42 ; EXPRESSION ANALYZER
_CMDL2 EQU 44 ; SECOND COMMAND LIST
_ACIA EQU 46 ; ACIA ADDRESS
_PAD EQU 48 ; CHARACTER PAD AND NEW LINE PAD
_ECHO EQU 50 ; ECHO/LOAD AND NULL BKPT FLAG
_PTM EQU 52 ; PTM ADDRESS
NUMVTR EQU 52/2+1 ; NUMBER OF VECTORS
HIVTR EQU 52 ; HIGHEST VECTOR OFFSET
; **************************************************
; * WORK AREA
; * THIS WORK AREA IS ASSIGNED TO THE PAGE ADDRESSED BY
; * -$1800,PCR FROM THE BASE ADDRESS OF THE ASSIST09
; * ROM. THE DIRECT PAGE REGISTER DURING MOST ROUTINE
; * OPERATIONS WILL POINT TO THIS WORK AREA. THE STACK
; * INITIALLY STARTS UNDER THE RESERVED WORK AREAS AS
; * DEFINED HEREIN.
; **************************************************
WORKPG EQU ROMBEG+RAMOFS ; SETUP DIRECT PAGE ADDRESS $ED00
SETDP WORKPG/$100 ; NOTIFY ASSEMBLER $ED
ORG WORKPG+256 ; READY PAGE DEFINITIONS $EE00
; * THE FOLLOWING THRU BKPTOP MUST RESIDE IN THIS ORDER
; * FOR PROPER INITIALIZATION
HERE *
ORG HERE-4
PAUSER EQU * ; PAUSE ROUTINE
ORG PAUSER-1
SWIBFL EQU * ; BYPASS SWI AS BREAKPOINT FLAG
ORG SWIBFL-1
BKPTCT EQU * ; BREAKPOINT COUNT
ORG BKPTCT-2
SLEVEL EQU * ; STACK TRACE LEVEL
ORG SLEVEL-NUMVTR*2
VECTAB EQU * ; VECTOR TABLE
ORG VECTAB-2*NUMBKP
BKPTBL EQU * ; BREAKPOINT TABLE
ORG BKPTBL-2*NUMBKP
BKPTOP EQU * ; BREAKPOINT OPCODE TABLE
ORG BKPTOP-2
WINDOW EQU * ; WINDOW
ORG WINDOW-2
ADDR EQU * ; ADDRESS POINTER VALUE
ORG ADDR-1
BASEPG EQU * ; BASE PAGE VALUE
ORG BASEPG-2
NUMBER EQU * ; BINARY BUILD AREA
ORG NUMBER-2
LASTOP EQU * ; LAST OPCODE TRACED
ORG LASTOP-2
RSTACK EQU * ; RESET STACK POINTER
ORG RSTACK-2
PSTACK EQU * ; COMMAND RECOVERY STACK
ORG PSTACK-2
PCNTER EQU * ; LAST PROGRAM COUNTER
ORG PCNTER-2
TRACEC EQU * ; TRACE COUNT
ORG TRACEC-1
SWICNT EQU * ; TRACE “SWI” NEST LEVEL COUNT
ORG SWICNT-1 ; (MISFLG MUST FOLLOW SWICNT)
MISFLG EQU * ; LOAD CMD/THRU BREAKPOINT FLAG
ORG MISFLG-1
DELIM EQU * ; EXPRESSION DELIMITER/WORK BYTE
ORG DELIM-40
ROM2WK EQU * ; EXTENSION ROM RESERVED AREA
ORG ROM2WK-21 ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<< for 6309 add two more byte: -23
TSTACK EQU * ; TEMPORARY STACK HOLD
STACK EQU * ; START OF INITIAL STACK
; *****************************************************
; * DEFAULT THE ROM BEGINNING ADDRESS TO 'ROMBEG'
; * ASSIST09 IS POSITION ADDRESS INDEPENDENT HOWEVER
; * WE ASSEMBLE ASSUMING CONTROL OF THE HARDWARE VECTORS.
; * NOTE THAT THE WORK RAM PAGE MUST BE 'RAMOFS'
; * FROM THE ROM BEGINNING ADDRESS.
; *****************************************************
ORG ROMBEG+$800 ; ROM ASSEMBLY/DEFAULT ADDRESS <<<<VECTOR TABLE ADDRESS
; * DPR->ASSIST09 WORK AREA PAGE
; * THE VECTOR TABLE AND DEFAULTS ARE INITIALIZED
; * ALL REGISTERS VOLATILE.
; *****************************************************
BLDVTR:
LEAX VECTAB,PCR ; ADDRESS VECTOR TABLE
TFR X,D ; OBTAIN BASE PAGE ADDRESS
TFR A,DP ; SETUP DPR
STA BASEPG ; STORE FOR QUICK REFERENCE
LEAU ,X ; RETURN TABLE TO CALLER
LEAY <INITVT,PCR ; LOAD FROM ADDR
STU ,X++ ; INIT VECTOR TABLE ADDRESS
LDB #NUMVTR-5 ; NUMBER OF RELOCATABLE VECTORS
PSHS B ; STORE INDEX ON STACK
BLD2 TFR Y,D ; PREPARE ADDRESS RESOLVE
ADDD ,Y++ ; TO ABSOLUTE ADDRESS
STD ,X++ ; INTO VECTOR TABLE
DEC ,S ; COUNT DOWN
BNE BLD2 ; BRANCH IF MORE TO INSERT
LDW #INTVE-INTVS ;<<<< HD6309
TFM Y+,X+ ;<<<< HD6309
LEAY ROM2OF,PCR ; TEST POSSIBLE EXTENSION ROM
LDX #$20FE ; LOAD "BRA *" FLAG PATTERN
CMPX ,Y++ ; ? EXTENDED ROM HERE
BNE BLDRTN ; BRANCH NOT OUR ROM TO RETURN
JSR ,Y ; CALL EXTENDED ROM INITIALIZE
BLDRTN PULS B,PC ; RETURN TO INITIALIZER
; *****************************************************
; * RESET ENTRY POINT
; * HARDWARE RESET ENTERS HERE IF ASSIST09 IS ENABLED
; * TO RECEIVE THE MC6809 HARDWARE VECTORS. WE CALL
; * THE BLDVTR SUBROUTINE TO INITIALIZE THE VECTOR
; * TABLE, STACK, AND THE FIREUP THE MONITOR VIA SWI
; * CALL.
; *****************************************************
RESET LEAS STACK,PCR ; SETUP INITIAL STACK
BSR BLDVTR ; BUILD VECTOR TABLE
RESET2 CLRA ; ISSUE STARTUP MESSAGE
TFR A,DP ; DEFAULT TO PAGE ZERO
SWI ; PERFORM MONITOR FIREUP
FCB MONITR ; TO ENTER COMMAND PROCESSION
BRA RESET2 ; REENTER MONITOR IF 'CONTINUE'
; *****************************************************
; * INITVT – INITIAL VECTOR TABLE
; * THIS TABLE IS RELOCATED TO RAM AND REPRESENTS THE
; * INITIAL STATE OF THE VECTOR TABLE. ALL ADDRESSES
; * ARE CONVERTED TO ABSOLUTE FORM. THIS TABLE STARTS
; * WITH THE SECOND ENTRY, ENDS WITH STATIC CONSTANT
; * INITIALIZATION DATA WHICH CARRIES BEYOND THE TABLE.
; *****************************************************
INITVT FDB CMDTBL-* ; DEFAULT FIRST COMMAND TABLE
FDB RSRVDR-* ; DEFAULT UNDEFINED HARDWARE VECTOR
FDB SWI3R-* ; DEFAULT SWI3
FDB SWI2R-* ; DEFAULT SWI2
FDB FIRQR-* ; DEFAULT FIRQ
FDB IRQR-* ; DEFAULT IRQ ROUTINE
FDB SWIR-* ; DEFAULT SWI ROUTINE
FDB NMIR-* ; DEFAULT NMI ROUTINE
FDB RESET-* ; RESTART VECTOR
FDB CION-* ; DEFAULT CION
FDB CIDAT-* ; DEFAULT CIDAT
FDB CIOFF-* ; DEFAULT CIOFF
FDB COON-* ; DEFAULT COON
FDB CODAT-* ; DEFAULT CODAT
FDB COOFF-* ; DEFAULT COOFF
FDB HSDTA-* ; DEFAULT HSDTA
FDB BSON-* ; DEFAULT BSON
FDB BSDAT-* ; DEFAULT BSDAT
FDB BSOFF-* ; DEFAULT BSOFF
FDB PAUSER-* ; DEFAULT PAUSE ROUTINE
FDB EXP1-* ; DEFAULT EXPRESSION ANALYZER
FDB CMDTB2-* ; DEFAULT SECOND COMMAND TABLE
; * CONSTANTS
INTVS FDB ACIA ; DEFAULT ACIA
FCB DFTCHP,DFTNLP ; DEFAULT NULL PADDS
FDB 0 ; DEFAULT ECHO
FDB PTM ; DEFAULT PTM
FDB 0 ; INITIAL STACK TRACE LEVEL
FCB 0 ; INITIAL BREAKPOINT COUNT
FCB 0 ; SWI BREAKPOINT LEVEL
FCB $39 ; DEFAULT PAUSE ROUTINE (RTS)
INTVE EQU *
CMDTBL equ *
RSRVDR equ *
SWI3R equ *
SWI2R equ *
FIRQR equ *
IRQR equ *
SWIR equ *
NMIR equ *
CION equ *
CIDAT equ *
CIOFF equ *
COON equ *
CODAT equ *
COOFF equ *
HSDTA equ *
BSON equ *
BSDAT equ *
BSOFF equ *
EXP1 equ *
CMDTB2 equ *
END
Hope it helps. If not maybe reach out to William Astle who wrote LWASM his contact info should be on his website. Which I linked to his documentation in the original post.
Hello Glen,
thank you for your suggestion: I saw it early this morning, and modify the source code this night;
It work, both with assem6309 and lwasm, the code seems to be OK.
So, the “issue” is due to the “*-x” evaluation by the assembler?
Sadly, it make the code less readable.
So, I think that I will comment it to the lwasm developers, maybe it’s a bug.
Again, Glen, thank you for your help and deep analyze of that problem.
When I “discover” lwasm, even with a well written manual, there is, at least for me, a lack of example of use of this masterpiece.
Have a nice day.
Kind regard.
-=chf=-
Hi chf,
I’m glad I could help, and I totally agree that LWASM is awesome but actual examples would take it to another level and allow more people to start using it.
Have a great day too,
Glen