Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Registers:
- SP (stack pointer): 16-bit
- FP (frame pointer): 16-bit
- PC (program counter): 16-bit
- A (left reg) 16-bit (or 32-bit)
- B (right reg) 16-bit (or 32-bit)
- 8-bit and 16-bit loads clear the top 16 bits, if present
- Addressing modes:
- <fast> = FP + item from lookup table
- <near> = FP + 8-bit sign extended offset
- <far> = FP + 16-bit offset
- <abs> = 16-bit address
- Fast stack reference:
- Code | location | assembler name
- -----+----------+----------------
- 0 | frame-24 | local12
- 1 | frame-22 | local11
- 2 | frame-20 | local10
- 3 | frame-18 | local9
- 4 | frame-16 | local8
- 5 | frame-14 | local7
- 6 | frame-12 | local6
- 7 | frame-10 | local5
- 8 | frame-8 | local4
- 9 | frame-6 | local3
- A | frame-4 | local2
- B | frame-2 | local1
- | frame-0 | old block pointer
- | frame+2 | old program counter
- C | frame+4 | arg1
- D | frame+6 | arg2
- E | frame+8 | arg3
- F | frame+10 | arg4
- .--------------------------------------------------------------------
- | 16-bit instructions
- '--------------------------------------------------------------------
- 0x : lda fast : A = <fast>
- 1x : ldb fast : B = <fast>
- 2x : push fast : push <fast> to the stack
- 3x : sta fast : <fast> = A
- 4x : lda #x : A = #x
- 5x : ldb #x : B = #x
- 6x : push #x : push #x to the stack
- 7x : add #x : A += #x
- 80 xx : lda near : A = <near>
- 81 xx xx : lda far : A = <far>
- 82 xx : ldb near : B = <near>
- 83 xx xx : ldb far : B = <far>
- 84 xx : push near : push <near> to the stack
- 85 xx xx : push far : push <far> to the stack
- 86 xx : sta near : <near> = A
- 87 xx xx : sta far : <far> = A
- 88 xx : lda #xx : A = #xx (sign extend)
- 89 xx xx : lda #xxxx : A = #xxxx
- 8A xx : ldb #xx : B = #xx (sign extend)
- 8B xx xx : ldb #xxxx : B = #xxxx
- 8C xx : push #xx : push #xx to the stack
- 8D xx xx : push #xxxx : push #xxxx to the stack
- 8E xx : add #xx : A += #xx (sign extend)
- 8F xx xx : add #xxxx : A += #xxxx
- 00-3f and 40-7f share logic except for sta/add
- 00-7f and 80-8f share logic
- 90 xx xx : lda xxxx : A = <abs>
- 91 xx xx : ldb xxxx : B = <abs>
- 92 xx xx : push xxxx : push <abs> to the stack
- 93 xx xx : sta xxxx : <abs> = A
- 94 xx xx : blda xxxx : A = <byte abs>
- 95 xx xx : bldb xxxx : B = <byte abs>
- 96 xx xx : bpush xxxx : push <byte abs> to the stack (zero extended)
- 97 xx xx : bsta xxxx : <byte abs> = A
- 98 xx xx : blda far : A = <byte far>
- 99 xx xx : bldb far : B = <byte far>
- 9A xx xx : bpush far : push <byte far> to the stack
- 9B xx xx : bsta far : <byte far> = A
- 9C xx xx : leaa far : A = &<far>
- 9D xx xx : leab far : B = &<far>
- 9E xx xx : pea far : push &<far> to the stack
- 9F xx xx : ?? far : reserved
- A0 : deref : A = *A
- A1 : popstore : pop B, *B = A
- A2 : bderef : A = (byte)*A
- A3 : bpopstore : pop B, (byte)*B = A
- A4 : pha : push A to the stack
- A5 : plb : pop B from the stack
- A6 xx : unstack #xx : sp += #xx (for cleaning up after a function)
- A7 xx xx : unstack #xxxx : sp += #xxxx
- A8 xx xx : call xxxx : call an address (push PC, PC = xxxx, push FP, FP = SP)
- A9 : callptr : call A
- AA xxxxyy: call xxxx, #yy : call an address, decrease the stack pointer by yy
- AB yy : callptr #yy : call A, decrease the stack pointer by yy
- AC : : operand size override prefix
- AD : : address size override prefix
- AE : return : return (SP = FP, pop FP, pop PC)
- AF : swap : A = B and B = A
- B0 : ucmplt : A = A < B (unsigned)
- B1 : ucmple : A = A <= B (unsigned)
- B2 : ucmpgt : A = A > B (unsigned)
- B3 : ucmpge : A = A >= B (unsigned)
- B4 : scmplt : A = A < B (signed)
- B5 : scmple : A = A <= B (signed)
- B6 : scmpgt : A = A > B (signed)
- B7 : scmpge : A = A >= B (signed)
- B8 : cmpeq : A = A == B
- B9 : cmpne : A = A != B
- BA : not : A = !A (or == 0)
- BB : neg : A = -A
- BC : compl : A = ~A
- BD : and : A = A & B
- BE : or : A = A | B
- BF : xor : A = A ^ B
- B0-B7 share logic
- entire block sets A
- C0 : add : A += B
- C1 : dec : A--
- C2 : rsub : A = B-A
- C3 : sub : A -= B
- C4 : lshift : A <<= B (unsigned)
- C5 : double : A <<= 1
- C6 : rshift : A >>= B (unsigned)
- C7 : arshift : A >>= B (signed)
- C8 : divu : A /= B (unsigned)
- C9 : divs : A /= B (signed)
- CA : modu : A %= B (unsigned)
- CB : mods : A %= B (signed)
- CC : mult : A *= B
- CD xy : sloadbf x,y : signed bit extract. a = b>>x, only keeping y bits (sign extended)
- CE xy : uloadbf x,y : unsigned bit extract. a = b>>x, only keeping y bits
- CF xy : storebf x,y : bit insert. a = (b&mask)|(a<<x)
- C0-C3 are all addition/subtraction
- C4-C7 are all shifting
- signed and unsigned opcodes share logic
- entire block sets A
- D0 xx : jumpt xx : PC += xx + 1 IF A==1
- D1 xx : jumpt xx : PC -= xx - 1 IF A==1
- D2 xx xx : jumpt xxxx : PC = <abs> IF A==1
- D3 xxyyzz: jumpt xxxxxx : PC = <long> IF A==1
- D4 xx : jumpf xx : PC += xx + 1 IF A==0
- D5 xx : jumpf xx : PC -= xx - 1 IF A==0
- D6 xx xx : jumpf xxxx : PC = <abs> IF A==0
- D7 xxyyzz: jumpf xxxxxx : PC = <long> IF A==0
- D8 xx : jump xx : PC += xx + 1
- D9 xx : jump xx : PC -= xx - 1
- DA xx xx : jump xxxx : PC = <abs>
- DB xxyyzz: jump xxxxxx : PC = <long>
- DC ?? : switchrange : switch statement with a range
- DD ?? : switchlist : switch statement with a list of values
- DE xx : in xx : input on port x (A = read value)
- DF xx : out xx : output on port x (write A to port)
- E0 : extenda : sign extend A from 8 bits to 16
- E1 : extendb : sign extend B from 8 bits to 16
- E0 xx xx : copy #xxxx : memcpy(b, a, #xxxx)
- E1 xx xx : mcmp #xxxx : memcmp(b, a, #xxxx)
- E2 xx xx : fill #xxxx : memset(b, a, #xxxx) ? maybe it'd be better as memcpy without changing b
- E3 xx xx : :
- E4 xx xx : :
- E5 xx xx : :
- E6 xx xx : :
- E7 xx xx : :
- E8 xx xx : :
- E9 xx xx : :
- EA xx xx : :
- EB xx xx : :
- EC : lda sp : A = sp
- ED : sta sp : sp = A
- EE xx : zalloc #xx : decrease stack pointer by a constant and fill newly allocated bytes with zeros
- EF xx : direct count : directly increase/decrease a variable
- direct count instruction takes a parameter:
- LLmm ffff
- |||| ++++- "Fast" stack reference, 12 local variables or 4 arguments
- ||++------ amount. index into 1, 2, -1, -2
- ++-------- 0 no special effect
- 1 load A with the new count value
- 2 use old count value as a pointer and load A with it. (increase by 1 means zero extended byte, 2 means word)
- 3 use old count value as a pointer and load it with A. (increase by 1 means byte, 2 means word)
- mnemonics:
- count var, 1 : directly count a variable up/down
- ldcount var, 1 : directly count a variable up/down and load the new value into A
- plcount var, 1 : directly count a variable up/down and use the old value as a pointer to load
- pscount var, 1 : directly count a variable up/down and use the old value as a pointer to store
- .--------------------------------------------------------------------
- | 32-bit instructions (operand size override)
- '--------------------------------------------------------------------
- AC 0x : lda32 fast : A = <fast>
- AC 1x : ldb32 fast : B = <fast>
- AC 2x : push32 fast : push <fast> to the stack
- AC 3x : sta32 fast : <fast> = A
- AC 80 xx : lda32 near : A = <near>
- AC 81 xx xx : lda32 far : A = <far>
- AC 82 xx : ldb32 near : B = <near>
- AC 83 xx xx : ldb32 far : B = <far>
- AC 84 xx : push32 near : push <near> to the stack
- AC 85 xx xx : push32 far : push <far> to the stack
- AC 86 xx : sta32 near : <near> = A
- AC 87 xxxxxxxx : sta32 far : <far> = A
- AC 89 xxxxxxxx : lda32 #xxxxxxxx : A = #xxxxxxxx
- AC 8B xxxxxxxx : ldb32 #xxxxxxxx : B = #xxxxxxxx
- AC 8D xxxxxxxx : push32 #xxxxxxxx : push #xxxxxxxx to the stack
- AC 8F xxxxxxxx : add32 #xxxxxxxx : A += #xxxxxxxx
- AC 90 xx xx : lda32 xxxx : A = <abs>
- AC 91 xx xx : ldb32 xxxx : B = <abs>
- AC 92 xx xx : push32 xxxx : push <abs> to the stack
- AC 93 xx xx : sta32 xxxx : <abs> = A
- AC A0 : deref32 : A = *A
- AC A1 : popstore32 : pop B, *B = A
- AC A4 : pha32 : push A to the stack
- AC A5 : plb32 : pop B from the stack
- AC B0 : ucmplt32 : A = A < B (unsigned)
- AC B1 : ucmple32 : A = A <= B (unsigned)
- AC B2 : ucmpgt32 : A = A > B (unsigned)
- AC B3 : ucmpge32 : A = A >= B (unsigned)
- AC B4 : scmplt32 : A = A < B (signed)
- AC B5 : scmple32 : A = A <= B (signed)
- AC B6 : scmpgt32 : A = A > B (signed)
- AC B7 : scmpge32 : A = A >= B (signed)
- AC B8 : cmpeq32 : A = A == B
- AC B9 : cmpne32 : A = A != B
- AC BA : not32 : A = !A (or == 0)
- AC C6 : rshift32 : A >>= B (unsigned)
- AC C7 : arshift32 : A >>= B (signed)
- AC C8 : divu32 : A /= B (unsigned)
- AC C9 : divs32 : A /= B (signed)
- AC CA : modu32 : A %= B (unsigned)
- AC CB : mods32 : A %= B (signed)
- AC E0 : extenda32 : sign extend A from 16 bits to 32
- AC E1 : extendb32 : sign extend B from 16 bits to 32
- .--------------------------------------------------------------------
- | Address size override (maybe 24-bit or 32-bit)
- '--------------------------------------------------------------------
- AD 90 xxxxxxxx : lda xxxxxxxx : A = <abs>
- AD 91 xxxxxxxx : ldb xxxxxxxx : B = <abs>
- AD 92 xxxxxxxx : push xxxxxxxx : push <abs> to the stack
- AD 93 xxxxxxxx : sta xxxxxxxx : <abs> = A
- AD 94 xxxxxxxx : blda xxxxxxxx : A = <byte abs>
- AD 95 xxxxxxxx : bldb xxxxxxxx : B = <byte abs>
- AD 96 xxxxxxxx : bpush xxxxxxxx : push <byte abs> to the stack (zero extended)
- AD 97 xxxxxxxx : bsta xxxxxxxx : <byte abs> = A
- AD A0 : deref : A = *A
- AD A1 : popstore : pop B, *B = A
- AD A2 : bderef : A = (byte)*A
- AD A3 : bpopstore : pop B, (byte)*B = A
- .--------------------------------------------------------------------
- | Operand and address size override
- '--------------------------------------------------------------------
- AC AD 90 xxxxxxxx : lda32 xxxxxxxx : A = <abs>
- AC AD 91 xxxxxxxx : ldb32 xxxxxxxx : B = <abs>
- AC AD 92 xxxxxxxx : push32 xxxxxxxx : push <abs> to the stack
- AC AD 93 xxxxxxxx : sta32 xxxxxxxx : <abs> = A
- AC AD A0 : deref32 : A = *A
- AC AD A1 : popstore32 : pop B, *B = A
- .--------------------------------------------------------------------
- | Code examples
- '--------------------------------------------------------------------
- -switch statements-
- switchrange
- .word 1, 5 ; range is 1 to 5
- .word default ; for if outside 1 to 5
- .word was1
- .word was2
- .word was3
- .word was4
- .word was5
- switchlist
- .word 5 ; 5 cases
- .word 1, was1
- .word 2, was2
- .word 3, was3
- .word 4, was4
- .word 5, was5
- .word default
- -array reading-
- lda index
- add #array_address
- deref
- -array writing-
- lda index
- add #array_address
- pha
- lda (whatever value to write)
- popstore
- -loop-
- lda #0
- sta index
- loop:
- ; get place to write
- lda #array
- ldb index
- add
- pha
- ; get index*index
- lda index
- ldb index
- mulu
- popstore
- lda index
- ldb #10
- cmpne
- jumpt loop
- -loop2-
- lda #0
- sta counter
- sta sum
- loop:
- count sum, 1
- ldcount counter, -1
- jumpt, loop
- return
- -strlen-
- lda #0
- sta length
- loop:
- lda arg1
- bderef
- jumpf exit
- lda length
- add #1
- sta length
- lda arg1
- add #1
- sta arg1
- jump loop
- exit:
- lda length
- return
- -strlen with count-
- lda #0
- sta length
- loop:
- plcount arg1, 1
- jumpf exit
- count length, 1
- jump loop
- exit:
- lda length
- return
- -utf8 strlen-
- zalloc #2 ; init length
- loop:
- plcount arg1, 1 ; a = *(arg1++)
- jumpf exit ; stop if it's zero (end of string)
- ldb #$80 ; characters < $80 are ASCII,
- ucmplt ; so they increase the counter
- jumpt yes
- ldb #$bf ; characters > $bf are starting characters
- ucmplt ; so they also increase the counter
- jumpf loop
- yes:
- count length, 1 ; length++
- jump loop
- exit:
- lda length ; return with length in A
- return
- -calling functions-
- push #1
- push #2
- push #3
- push #4
- call sum
- unstack #4*2
- sum:
- lda arg1
- ldb arg2
- add
- ldb arg3
- add
- ldb arg4
- add
- return
- -passing -
- pea variable
- call function
- unstack #1*2
- function: ; writes 1 to the passed argument
- push arg1
- lda #1
- popstore
- return
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement