flat assembler
Message board for the users of flat assembler.

Index > Heap > m3ntal's Diary: Code, Macros, Previews

Goto page Previous  1, 2, 3, 4  Next
Author
Thread Post new topic Reply to topic
m3ntal



Joined: 08 Dec 2013
Posts: 296
m3ntal
tthsqe: Nice algorithm+code. Looks good even in 4/5BPP (16/32 colors).

Preview of 6502 Assembler for Nintendo created with FASMW. First example working.

Syntax is standard except for one change: Immediate must be prefixed with = (instead of #). Example:
Code:
lda =$7F     ; immediate (prefix with =)
lda $80      ; zero page memory
lda $80, x   ; zero page, x
lda $A000    ; absolute memory
lda $8000, x ; absolute, x
lda $8000, y ; absolute, y
lda ($7F, x) ; (indirect, x)
lda ($7F), y ; (indirect), y    


Description:
Filesize: 40.89 KB
Viewed: 8133 Time(s)

nesp.jpg


Post 16 Feb 2014, 02:18
View user's profile Send private message Reply with quote
m3ntal



Joined: 08 Dec 2013
Posts: 296
m3ntal
Zymic restored my sites/images/downloads. Their servers crash 1-2 times per month.

Ideas and pseudo-code for a C-style macro language. Super+C ML (SCML). Easy syntax, standard names, no setup, works out-of-box, runs anywhere (MicroSD), lightning fast compile+run (usually <1 second!), no waiting 10-30+ seconds, predefined library AND portability to various CPUs+systems. I can generate code for Intel, ARM, MOS 6502, Zilog Z80 and Motorola 68k (< this one is a confusing beast!).

I wonder what C/C++ programmers would think of this. It's basically C without all the bull!@#$ (thought of naming it: C-BS, minus BS). It seems comfortable, tempting to try.
Code:
; Minimal example...

include 'c'

int i
char *s="Super+C!"

main
  for i=0, i<3, i++
    printf "Hello, %s", s
  endl
endf    
Code:
; File I/O...

include 'c'

uint f             ; file handle

char *name="FILE.TXT"
char *s="EXAMPLE TEXT DATA"
char *e="Open failed"

main
  get f=fopen \    ; open for w
   name, 'wt'      ; in text mode
  if f=0           ; error
    puts e         ; display message
    return 0       ; 0=error
  end
  fputs f, s       ; write string+nl
  fputi f, 1234567 ; write 32BIT integer
  fputr f          ; write return/nl
  fwrite f, s, 7   ; first 7 bytes
  fputc f, 0       ; terminator
  fclose f         ; close handle
  fexecute name    ; execute
endf    
Code:
; Dynamic allocation

include 'c'

void *p=0
int n
char *s="!sseccuS"

main
  get p=malloc 256  ; allocate
  if p=0            ; error
    puts "Error"
    return 0
  end
  memset p, 0, 256  ; initialize
  memset p, 'A', 16 ; copy 16 'A's
  puts p
  get n=strlen s    ; source length
  puti n
  . n++             ; size
  memcpy p, s, n    ; copy message
  strrev p          ; reverse
  puts p
  free p            ; deallocate (+p=0)
endf    


Description: ZDS Preview
Filesize: 89.46 KB
Viewed: 8067 Time(s)

zds5.jpg


Post 27 Feb 2014, 02:24
View user's profile Send private message Reply with quote
typedef



Joined: 25 Jul 2010
Posts: 2913
Location: 0x77760000
typedef
Yeah, so how do you handle string lengths in your code. Java style? Razz

Coz I ain't seen no null terminator nowhere.
Post 27 Feb 2014, 05:13
View user's profile Send private message Reply with quote
m3ntal



Joined: 08 Dec 2013
Posts: 296
m3ntal
Code:
int n
char *s="Super+C"
char s[]="Super+C"
char s[8]="Super+C"
; ...
get n=strlen s    
Code:
; 2-DO: HL STRING structure with safety,
; portability and automatic allocation.
; uses LL routines

struct STRING
  uchar id, type  ; type/etc. 0=ASCII
  uchar case, r   ; sensitivity, reserved
  uint n          ; # characters
  void *p         ; pointer
  uint size       ; allocation size
ends ?string      ; 16 bytes in I32

; 2-DO: maybe HL String class with operators:
; = for copy/compare, + for attach,
; =[i] for character, =&[i] for address.    
Post 27 Feb 2014, 05:46
View user's profile Send private message Reply with quote
tthsqe



Joined: 20 May 2009
Posts: 724
tthsqe
mental,
Have you been able to get some examples running on a raspberry pi emulator? I would like to try to make something on raspberry pi, but I have not been able to get an emulator working. Any examples with
- drawings bitmaps to the screen
- allocating/de-allocating memory
- getting keyboard input
would be appreciated.

EDIT: Got the emulator qemu, but still wondering how to make a program for raspberry pi.
Post 28 Feb 2014, 00:19
View user's profile Send private message Reply with quote
m3ntal



Joined: 08 Dec 2013
Posts: 296
m3ntal
Here's a QEMU+RPI distribution that works on Win7. Loading takes a long time (9+ minutes on my system). Login: pi Password: raspberry Then startx. My RPI has been collecting dust for the last 5 months.

IMO, a good way to learn and practice ARM is by using QEMU with PL110 LCD or VisualBoyAdvance emulator.

Input depends on the system (bare-metal, linux, risc). Drawing can be portable. Example:
Code:
; address &vga[(y*(screen.w*2))+(x*2)].
; a1/a2=x/y...

align 4
vga.xy:
 push v1, lr
 movi a3, SCREEN.PITCH
 mul a4, a2, a3        ; a4=y*pitch+(x*2)
 add a4, a4, a1, lsl 1
 movi a2, VGA          ; video
 add a1, a2, a4        ; return a2+a4
pop v1, pc

; draw 16BPP bitmap with transparency.
; a1-a4=x/y/w/h. v7=pixels...

align 4
draw.bitmap.t:
 push v1-v7, lr
 mov v3, a3            ; save size
 mov v4, a4
 bl vga.xy
 movi a2, SCREEN.PITCH ; screen w in bytes
 mov a4, v3, lsl 1     ; image w in bytes
 ldrh v5, [v7]
 .y:
  mov a3, v3
  .x:
   ldrh v1, [v7], 2    ; get pixel
   cmp v1, v5          ; transparent?
   strneh v1, [a1]     ; store if opaque
   add a1, a1, 2       ; increment regardless
   subs a3, a3, 1      ; w # times
  bne .x
  add a1, a1, a2       ; advance
  sub a1, a1, a4       ; destiny pointer
  subs v4, v4, 1       ; h # times
 bne .y
pop v1-v7, pc

; note: movi loads/constructs 8-32BIT immediate
; value. push/pop = load/store multiple    
Post 28 Feb 2014, 17:24
View user's profile Send private message Reply with quote
m3ntal



Joined: 08 Dec 2013
Posts: 296
m3ntal
I'm thinking about getting a Microsoft Surface RT just for programming. Price has lowered to $200 for the 32GB model. According to sources, it will not run executables unless they were produced by the latest VisualStudio and officially signed by M$, but there is a jailbreak crack that allows it to run unsigned EXEs. VS is currently the only way to do programming for RT... until I get one Smile M$ can't compete with my development utilities.

My Magic-ARM assembler created with FASM preprocessor:
Code:
; $$$$$$$$$$$$$$$$$$ MAGIC-ARM $$$$$$$$$$$$$$$$$$$
; *************** STAR^2 SOFTWARE ****************
; ??????????????????? ARM.INC ????????????????????
;                               _
;            ?__. .__ __ ____ _(_) __?
;            /  |/  / @ `/ $ `/ / __/
;           /_/|_/_/\_,_/\_, /_/\__/
;                       /___/

;        Magic-ARM Assembler+Compiler *Beta*

;;;;;;;;;;;;;;;;;;;;;; CPU ;;;;;;;;;;;;;;;;;;;;;;;

; QEMU: ARM.v7M  ; Angel + PrimeCell LCD
; RPI:  ARM.v6Z  ; Raspberry PI: ARM1176JZF-S
; MINI: ARM.v5TE ; Minimal. Windows Mobile?
; GBA:  ARM.v4T  ; GameBoy Advance: ARM7TDMI

numeric ARM.*,\
 v4, v4T, v5, v5T, v5TE, v5TEJ, v6, v6T2,\
 v6Z, v6K, v6M, v7M, v7EM, v7R, v7A, v8A

@CPU=ARM.v5TE

if.cpu     fix if @CPU>=
if.not.cpu fix if @CPU<

macro verify.cpu x {
 if.not.cpu x
  'Unsupported by selected CPU'
 end if
}

@a=0 ; base address
@$=0 ; current offset (10000h in QEMU)

@a$ fix (@a+@$)

; write instruction then advance @$

macro @arm i {
 if.not.align @$, 4
  'Address not aligned'
 end if
 dd i
 @$=@$+4
}

macro @align n {
 while @$ mod n<>0
  db 0
  @$=@$+1
 end while
}

align fix @align

macro @nop { @arm 0E1A00000h } ; mov r0, r0

; 31-28   27-20  19-16 15-12  98 7654 3210
; [CCCC/OOOO/PPPP/AAAA/BBBB/CCCC/DDDD/EEEE]

macro @arm1 C, o, p, a, b, c, d, e {
 @arm (C.#C shl 28) or ((o) shl 24) or \
  ((p) shl 20) or ((a) shl 16) or \
  ((b) shl 12) or ((c) shl 8) or \
  ((d) shl 4) or (e)
}

;;;;;;;;;;;;;;;;;;; REGISTERS ;;;;;;;;;;;;;;;;;;;;

numeric \
 r0, r1, r2, r3, r4, r5, r6, r7,\
 @8, @9, @10, @11, @12, @13, @14, @15

a1 fix r0   ; a/rgument registers: a1-a4
a2 fix r1
a3 fix r2
a4 fix r3

v1 fix r4   ; v/ariable/scratch
v2 fix r5   ; registers: v1-v8
v3 fix r6
v4 fix r7
v5 fix @8
v6 fix @9
v7 fix @10
v8 fix @11

@sp fix @13 ; stack
@lr fix @14 ; link
@pc fix @15 ; program counter

;;;;;;;;;;;;;;;;;;; CONDITIONS ;;;;;;;;;;;;;;;;;;;

numeric C.*,\
 eq, ne, hs, lo, mi, pl, vs, vc,\
 hi, ls, ge, lt, gt, le, al, nv

;;;;;;;;;;;;;;;;; BARREL SHIFTER ;;;;;;;;;;;;;;;;;

; 31-28   25 24-21 20 19-16 15-12 987654/3210
; [CCCC/00/I/OPCODE/S/RNXX/RDXX/OPERAND2/XXXX]

;         /I=0: SHIFT R        /IIIIIIII/RMXX/
;         /I=1: SHIFT I        /SHXX/IIIIIIII/

; @asr r0, 16 ; mov r0, r0, asr 16
; @lsl r1, r2 ; mov r1, r1, lsl r2

; create shift instructions...

numeric SH.*, lsl, lsr, asr, ror

irps x, lsl lsr asr ror {
 macro @#x a, b \{
  verify.r a
  if b ?is.r
   @arm 0E1A00000h or (a shl 12) or \
    (b shl 8) or (SH.\#x shl 5) or \
    10000b or a
  else if b ?is.i
   verify.shn x, b
   @arm 0E1A00000h or (a shl 12) or \
    (b shl 7) or (SH.\#x shl 5) or a
  else
   'Source must be R/I:' b
  end if
 \}
 macro @#x#s a, b \{ ; s/et flags
  verify.r a
  if b ?is.r
   @arm 0E1B00000h or (a shl 12) or \
    (b shl 8) or (SH.\#x shl 5) or \
    10000b or a
  else if b ?is.i
   verify.shn x, b
   @arm 0E1B00000h or (a shl 12) or \
    (b shl 7) or (SH.\#x shl 5) or a
  else
   'Source must be R/I:' b
  end if
 \}
}

macro verify.shs s {
 if ?not s in <lsl,lsr,asr,ror>
  'Shift expected:' s
 end if
}

macro verify.shn s, n {
 if s eq lsl | s eq ror
  verify.n n, 0, 31
 else
  verify.n n, 1, 32
 end if
}

macro verify.sh s, n {
 verify.shs s
 if ?not n ?is.r
  verify.shn s, n
 end if
}

macro @test.sh {
 @lsl r0, r1
 @lsr r3, r4
 @asr r5, r7
 @ror r5, 7
 @lsls r0, r1
 @lsrs r3, r4
 @asrs r5, r7
 @rors r5, 7
}

;;;;;;;;;;;;;;;;;;;; TRANSFER ;;;;;;;;;;;;;;;;;;;;

; 31-28 27-24 23-0         9876543210
; [CCCC/101L/IIIIIIIIIIIIIIIIIIIIIIII]

; branch + link register...

; calculate 24BIT relative address:

; (((((o)-_begin_)-($-_begin_)-Cool shr 2) \
;  and 0FFFFFFh)

; create 32 bxx+blxx instructions...

irps x, eq ne hs lo mi pl vs vc \
 hi ls ge lt gt le al nv {
 macro @b#x o \{
  verify.a (o), 4
  @arm (C.\#x shl 28) or (101b shl 25) \
   or (((((o)-_begin_)-($-_begin_)-8) shr 2) \
   and 0FFFFFFh)
 \}
 macro @bl#x o \{
  verify.a (o), 4
  @arm (C.\#x shl 28) or (101b shl 25) \
   or (((((o)-_begin_)-($-_begin_)-8) shr 2) \
   and 0FFFFFFh) or (1 shl 24)
 \}
}

@bl fix @blal

macro @test.b {
 local a, b, c, d
 a: @beq d
 @nop
 b: @bgt c
 @nop
 c: @blt b
 @nop
 d: @bmi a
 @bl a
}

; branch with link and exchange

macro @blx r {
 verify.cpu ARM.v5T
 verify.r r
 @arm 0E12FFF30h or r
}

; branch and change to Jazelle state

macro @bxj r {
 verify.cpu ARM.v5TEJ
 verify.r r
 @arm 0E12FFF20h or r
}

; software interrupt: swi/svc

macro @swi n {
 verify.n n, 0, 0FFFFFFh
  @arm 0EF000000h or n
}

macro @svc n { @swi n }

; breakpoint

macro @bkpt n {
 verify.cpu ARM.v5T
 verify.i n
 verify.u16 n
 @arm 0E1200000h or \
  (((n shr 4) and 0FFFh) shl 8) \
  or (n and 0Fh) or (7 shl 4)
}

;;;;;;;;;;;;;;;;;;; IMMEDIATE ;;;;;;;;;;;;;;;;;;;;

; load/construct 8-32BIT immediate/address...

macro @ldi a, b {
 local n
 verify.r a
 verify.i b
 if (b)=-1 | (b)=0FFFFFFFFh ; -1/0FFFFFFFFh
  @mvns a, 0                ; mvns a, 0
 else if (b)>=0 & (b)<=255  ; 8BIT
  @arm (0E3Bh shl 20) or \  ; movs a, b
   (a shl 16) or \
   (a shl 12) or b
 else if \
  ((b) and 0FFFF00FFh)=0    ; any byte
  @arm 0E3B00C00h or \      ; shift left?
   (a shl 12) or (b shr 8)  ; including
 else if \                  ; powers of 2
  ((b) and 0FF00FFFFh)=0    ; FF0000h
  @arm 0E3B00800h or \
   (a shl 12) or (b shr 16)
 else if \
  ((b) and 00FFFFFFh)=0     ; 0FF000000h
  @arm 0E3B00400h or \
   (a shl 12) or (b shr 24)
 else if \
  ((b) and 0FFFFF00Fh)=0    ; odd bytes...
  @arm 0E3B00E00h or \      ; FF0h
   (a shl 12) or (b shr 4)
 else if \
  ((b) and 0FFF00FFFh)=0    ; 0FF000h
  @arm 0E3B00A00h or \
   (a shl 12) or (b shr 12)
 else if \
  ((b) and 000FFFFFh)=0     ; 0FF00000h
  @arm 0E3B00600h or \
   (a shl 12) or (b shr 20)
 else                       ; build value...
  n=(b) and 0FFh
  @arm (0E3Bh shl 20) or \  ; movs a, b&0FFh
   (a shl 16) or \
   (a shl 12) or n
  n=((b) and 0FF00h) shr 8
  if n<>0
   @arm (0E39h shl 20) \    ; orrs a, a, b&0FF00h
    or (a shl 16) \
    or (a shl 12) \
    or 0C00h or n           ; orrs if 16/24BIT...
  end if
  n=((b) and 0FF0000h) \
   shr 16
  if n<>0
   @arm (0E39h shl 20) or (a shl 16) or \
    (a shl 12) or 800h or n
  end if
  n=((b) and 0FF000000h) shr 24
  if n<>0
   @arm (0E39h shl 20) or (a shl 16) or \
    (a shl 12) or 400h or n
  end if
 end if
}

macro @test.ldi {
 @ldi r3, -1
 @ldi r3, 0ABh
 @ldi r3, 07F0h
 @ldi r3, 07F00h
 @ldi r3, 07F000h
 @ldi r3, 07F0000h
 @ldi r3, 07F00000h
 @ldi r3, 0FF000000h
 @ldi r3, 080000000h
 @ldi r3, 1234h
}

; movw/movt 16BIT immediate: ARM.v6T2...

; W: [CCCC/0011/0000/IIII/RDXX/IIIIIIIIIIII]
; T: [CCCC/0011/0100/IIII/RDXX/IIIIIIIIIIII]

macro @movwx name, o {
 macro @#name a, b \{
  verify.cpu ARM.v6T2
  verify.r a
  verify.u16 b
  @arm 0E3000000h or (o shl 20) \
   or (a shl 12) or ((b and 0F000h) \
   shl 4) or (b and 0FFFh)
 \}
}

@movwx movw, 0
@movwx movt, 100b

macro @movwt r, i {
 @movw r, (i and 0FFFFh)
 if i>0FFFFh
  @movt r, ((i and 0FFFF0000h) shr 16)
 end if
}

; "move immediate" depending on CPU

macro @movi r, i {
 verify.r r
 verify.i i
 if.cpu ARM.v6T2
  @movwt r, i
 else
  @ldi r, i
 end if
}

; count leading zeros

macro @clz a, b {
 verify.cpu ARM.v5T
 verify.r a, b
 @arm 0E16F0F10h or (a shl 12) or b
}

; get current+saved program status
; register. s=CPSR/SPSR...

macro @mrs r, s {
 verify.r r
 if s eq CPSR
  @arm 0E10F0000h or (r shl 12)
 else if s eq SPSR
  @arm 0E14F0000h or (r shl 12)
 end if
}

; set CPSR/SPSR = register. c=PSR BITs:

; CPSR_f/s/x/c/fs/fsxc
; SPSR_f/s/x/c/fs/fsxc

; no APSR synonms, use CPSR equivelants

numeric CPSR_*,\
 f=28h, s=24h, x=22h, c=21h, fs=2Ch, fsxc=2Fh

numeric SPSR_*,\
 f=68h, s=64h, x=62h, c=61h, fs=6Ch, fsxc=6Fh

macro @msr c, r {
 verify.r r
 if ?not c in \
  <CPSR_f,CPSR_s,CPSR_x,CPSR_c,CPSR_fs,\
   CPSR_fsxc,SPSR_f,SPSR_s,SPSR_x,SPSR_c,\
   SPSR_fs,SPSR_fsxc>
  'Invalid field:' c
 end if
 @arm 0E100F000h or (c shl 16) or r
}

macro @test.mrs {
 @mrs r7, CPSR
 @mrs r7, SPSR
 @msr CPSR_f, r5
 @msr CPSR_s, r5
 @msr CPSR_x, r5
 @msr CPSR_c, r5
 @msr CPSR_fs, r5
 @msr CPSR_fsxc, r5
 @msr SPSR_f, r5
 @msr SPSR_s, r5
 @msr SPSR_x, r5
 @msr SPSR_c, r5
 @msr SPSR_fs, r5
 @msr SPSR_fsxc, r5
}

;;;;;;;;;;;;;;;;;; LOAD & STORE ;;;;;;;;;;;;;;;;;;

; [CCCC/01IP/UBWL/RNXX/RDXX/IIIIIIIIIIII]

; I  - Immediate (1) or register/shift (0)?
; P  - Pre-post? Add/subtract offset before
;      (P=1) or after (P=0) transfer
; U  - Up/down. Add (U=1) or subtract offset
; B  - Byte? 0=Word, 1=Byte
; W  - Write-back address to base?
; L  - Load or store? 1=Load. 0=Store
; RN - Base register
; RD - Source/destiny
; II - 12BIT offset or shift+r (S+M)

macro @ls cc, l, z, r, [p] {
 common
  local ?a, ?b
  ?a=0
  ?b=0
  syntax 0
   match =0 \          ; ldr r, [b, i, sh #]!
    [b=,i=,sh s]=!, \  ; scaled register
    ?s p \{            ; pre-index
    verify.r b, i
    verify.i s
    verify.sh sh, s
    ?a=05Ah or 100000b
    ?b=(b shl 16) or \
     (s shl 7) or \
     (SH.\#sh shl 5) \
     or i
   syntax 1
  \}
  match =0 [b=,o]=!, \ ; ldr r, [b, o]!
   ?s p \{
   verify.r b
   if o ?is.r          ; register pre-index
    ?a=078h or 10b     ; ldr r, [b, ri]!
    ?b=(b shl 16) or o
   else if o ?is.i     ; ldr r, [b, #]!
    verify.12 o
    if o<0
     ?a=050h or 10b    ; negative
     ?b=(b shl 16) \
      or (0-o)
    else
     ?a=058h or 10b    ; positive
     ?b=(b shl 16) \
      or o
    end if
   else
    'Unexpected:' o
   end if
   syntax 1
  \}
  match =0 \           ; ldr r, [b, i, sh #]
   [b=,i=,sh s], \     ; scaled register
   ?s p \{             ; post-index
   verify.r b, i
   verify.i s
   verify.sh sh, s
   ?a=078h
   ?b=(b shl 16) or \
    (s shl 7) or \
    (SH.\#sh shl 5) \
    or i
   syntax 1
  \}
  match =0 [b]=,-n, \  ; ldr r, [b], -#
   ?s p \{             ; negative immediate
   verify.r b          ; post-index
   verify.i n
   verify.12 n
   ?a=040h
   ?b=(b shl 16) or n
   syntax 1
  \}
  match =0 [b]=,o, \   ; ldr r, [b], o
   ?s p \{
   verify.r b
   if o ?is.r          ; ldr r, [b], ro
    ?a=068h
    ?b=(b shl 16) or o ; register post-index
    syntax 1
   else if o ?is.i     ; ldr r, [b], #
    verify.12 o
    if o<>0
     ?a=048h
    else
     ?a=058h
    end if
    ?b=(b shl 16) or o ; immediate post-index
    syntax 1
   else
    'Unexpected:' o
   end if
  \}
  match =0 [b=,o], \   ; ldr r, [b, o]
   ?s p \{
   if o ?is.r          ; ldr r, [b, ri]
    ?a=078h            ; register post-index
    ?b=(b shl 16) or o
   else if o ?is.i     ; ldr r, [b, #]
    verify.12 o        ; immediate post-index
    if o>=0            ; positive
     ?a=58h
     ?b=(b shl 16) \
      or o
    else               ; negative
     ?a=50h
     ?b=(b shl 16) \
      or (0-o)
    end if
   else
    'Unexpected:' o
   end if
   syntax 1
  \}
  match =0 [b], \      ; ldr r, [b]
   ?s p \{
   ?a=58h
   if b ?is.r          ; base=register
    ?b=(b shl 16)
   else if b ?is.i     ; immediate
    verify.12 b        ; pc relative
    ?b=($-_begin_)-b+8
    if ?b>=0           ; positive
     ?a=51h
    else               ; negative
     ?a=59h
     ?b=0-?b
    end if
    ?b=?b or \
     (0Fh shl 16)      ; base=pc
   else
    'Unexpected:' b
   end if
   syntax 1
  \}
 verify ls
 @arm (C.#cc shl 28) or (z shl 22) or \
  (l shl 20) or (?a shl 20) or \
  (r shl 12) or ?b
}

macro @ldr [p]  { common @ls al, 1, 0, p }
macro @str [p]  { common @ls al, 0, 0, p }

macro @ldrb [p] { common @ls al, 1, 1, p }
macro @strb [p] { common @ls al, 0, 1, p }

macro @test.ls {
 @ldr r0, [123h]
 @ldr r0, [-123h]
 @ldr r0, [r1]
 @ldr r0, [r1], 1
 @ldr r0, [r1], -1
 @ldr r0, [r1, r2]
 @ldr r0, [r1, 1]
 @ldr r0, [r1, -1]
 @ldr r0, [@15, 0ABCh]
 @ldr r0, [@15, -0ABCh]
 @ldr r0, [r7, 0ABCh]
 @ldr r0, [r7, -0ABCh]
 @ldr r0, [r1, r2, lsl 3]
 @ldr r0, [r1, 777h]!
 @ldr r0, [r1, -777h]!
 @ldr r0, [r1, r2]!
 @ldr r0, [r1, r2, lsl 3]!
}

macro @test.lsb {
 @ldrb r5, [r7]
 @strb r5, [r7]
}

;;;;;;;; LOAD/STORE SIGNED BYTE/HALF/DUAL ;;;;;;;;

; [CCCC/000P/UIWL/RNXX/RDXX/0000/1SH1/RMXX]
; [CCCC/000P/UIWL/RNXX/RDXX/IIII/1SH1/IIII]
;  CCCC/       /L/    /RRRR/    /XXXX/

; @ldrsb r2, [r7]
; @ldrsh r2, [r7, 48h]!
; @ldrh r2, [r7, -48h]
; @ldrd r2, [r7], 8
; @strh r2, [r7], -4
; @strd r3, [r7, 128]

macro @lsx cc, l, x, r, [p] {
 common
  local pi, u, i, n, w
  pi=0                  ; pre-index?
  u=0                   ; up/down? add/sub
  i=0                   ; immediate?
  n=0                   ; number
  w=0                   ; write-back?
  verify.r r
  syntax 0
  match =0 [b=,o]!,\    ; lsx r, [b,o]!
   ?s p \{
   pi=1                 ; pre-index
   u=1                  ; up/add
   w=1                  ; write-back
   verify.r b
   if o ?is.r           ; base=register
    @arm1 cc, pi,\
     (u shl 3) or (i shl 2) or\
     (w shl 1) or l, b, r,\
     0, x, o
   else if o ?is.i      ; immediate
    i=1
    n=o
    if n<0              ; negative
     n=0-n
     u=0                ; down/sub
    end if
    verify.u8 n
    @arm1 cc, pi,\
     (u shl 3) or (i shl 2) or\
     (w shl 1) or l, b, r,\
     ((n and 0F0h) shr 4),\
     x, (n and 0Fh)
   else
    'Unexpected:' o
   end if
   syntax 1
  \}
  match =0 [b=,o],\     ; lsx r, [b,o]
   ?s p \{
   pi=1                 ; pre-index
   u=1                  ; up/add
   verify.r b
   if o ?is.r           ; base=register
    @arm1 cc, pi,\
     (u shl 3) or (i shl 2) or\
     (w shl 1) or l, b, r,\
     0, x, o
   else if o ?is.i      ; immediate
    i=1
    n=o
    if n<0              ; negative
     n=0-n
     u=0                ; down/sub
    end if
    verify.u8 n
    @arm1 cc, pi,\
     (u shl 3) or (i shl 2) or\
     (w shl 1) or l, b, r,\
     ((n and 0F0h) shr 4),\
     x, (n and 0Fh)
   else
    'Unexpected:' o
   end if
   syntax 1
  \}
  match =0 [b]=,o, \    ; lsx r, [b], o
   ?s p \{
   verify.r b
   if o ?is.r           ; lsx r, [b], r
    @arm1 cc, pi,\
     (1000b or l),\
     b, r, 0, x, o
    syntax 1
   else                 ; lsx r, [b], -/i/-r
    syntax 0
    match -O, o \\{     ; lsx r, [b], -r
     if O ?is.r
      @arm1 cc, pi,\
      l, b, r, 0, x, O
      syntax 1
     else               ; lsx r, [b], -i
      u=0
      i=1
      verify.8 O
      @arm1 cc, pi,\
       (u shl 3) or (i shl 2) or\
       (w shl 1) or l, b, r,\
       ((O shr 4) and 0Fh),\
       x, (O and 0Fh)
      syntax 1
     end if
    \\}
    if.syntax 0
     if o ?is.i         ; lsx r, [b], i
      u=1
      i=1
      verify.8 o
      @arm1 cc, pi,\
       (u shl 3) or (i shl 2) or\
       (w shl 1) or l, b, r,\
       ((o shr 4) and 0Fh),\
       x, (o and 0Fh)
      syntax 1
     else
      'Unexpected:' o
     end if
    end if
   end if
  \}
  match =0 [b], ?s p \{ ; lsx r, [b]
   pi=1                 ; pre-index
   if b ?is.r           ; base=register
    u=1                 ; up
    i=1                 ; immediate (0)
    @arm1 cc, pi,\
     (u shl 3) or (i shl 2) or\
     (w shl 1) or l, b, r,\
     0, x, 0
   else if b ?is.i      ; immediate
    i=1
    n=($-_begin_)-b+8   ; pc relative
    verify.8 n
    if n>0              ; positive
     u=0
     @arm1 cc, pi,\
      (u shl 3) or (i shl 2) or\
      (w shl 1) or l, 0Fh, r,\
      ((n and 0F0h) shr 4),\
      x, (n and 0Fh)
    else                ; negative
     u=1
     n=0-n
     @arm1 cc, pi,\
      (u shl 3) or (i shl 2) or\
      (w shl 1) or l, 0Fh, r,\
      ((n and 0F0h) shr 4),\
      x, (n and 0Fh)
    end if
   else
    'Unexpected:' b
   end if
   syntax 1
  \}
 verify
}

numeric LDR.*,\
 SB=1101b, SH=1111b, H=1011b, D=1101b

numeric STR.*, H=LDR.H, D=LDR.SH

macro @ldrsb r, [p]
 { common @lsx al, 1, LDR.SB, r, p }

macro @ldrsh r, [p]
 { common @lsx al, 1, LDR.SH, r, p }

macro @ldrh r, [p]
 { common @lsx al, 1, LDR.H, r, p }

macro @strh r, [p]
 { common @lsx al, 0, STR.H, r, p }

macro verify.re r {
 if (r and 1)<>0
  'Register must be even' r
 end if
}

macro @ldrd r, [p] {
 common verify.re r
  @lsx al, 0, LDR.D, r, p
}

macro @strd r, [p] {
 common verify.re r
  @lsx al, 1, STR.D, r, p
}

macro @test.lsx {
 @ldrsb r2, [48h]
 @ldrsb r2, [-48h]
 @ldrsb r2, [r7]
 @ldrsh r2, [r7]
 @ldrh r2, [r7]
 @ldrd r2, [r7]
 @strd r2, [r7]
 @ldrsb r2, [r7], 48h
 @ldrsb r2, [r7], -48h
 @ldrsb r2, [r7], r3
 @ldrsb r2, [r7], -r5
 @ldrsb r2, [@pc, r5]
 @ldrsb r2, [@pc, 48h]
 @ldrsb r2, [r7, r5]
 @ldrsb r2, [r7, 48h]
 @ldrsb r2, [r7, -48h]
 @ldrsb r2, [r7, 48h]!
 @ldrsb r2, [r7, -48h]!
}

;;;;;;;;;;;; EASY LOAD/STORE TYPE/SIZE ;;;;;;;;;;;

macro @xls name, a, b, n, i {
 if i eq
  @#name a, b
 else
  @#name a, b, (i*n)
 end if
}

macro @ldx a, b, s, i {
 if s eq i8
  @xls ldrsb, a, b, 1, i
 else if s eq u8
  @xls ldrb, a, b, 1, i
 else if s eq i16
  @xls ldrsh, a, b, 2, i
 else if s eq u16
  @xls ldrh, a, b, 2, i
 else if s eq i32 | s eq u32
  @xls ldr, a, b, 4, i
 else if s eq i64 | s eq u64
  @xls ldrd, a, b, 8, i
 else
  'Invalid type/size:' s
 end if
}

macro @stx a, b, s, i {
 if s eq i8 | s eq u8
  @xls strb, a, b, 1, i
 else if s eq i16 | s eq u16
  @xls strh, a, b, 2, i
 else if s eq i32 | s eq u32
  @xls str, a, b, 4, i
 else if s eq i64 | s eq u64
  @xls strd, a, b, 8, i
 else
  'Invalid type/size:' s
 end if
}

;;;;;;;;;;;;; CONDITIONAL LOAD/STORE ;;;;;;;;;;;;;

; @str:h:ne r1, [r2]

macro @ldr [p] {
 common
  syntax 0
  match :x:c r=,s, p \{ ; ldr:x:c
   if x eq b
    @ls c, 1, 1, r, s
   else if x eq sb
    @lsx c, 1, LDR.SB, r, s
   else if x eq h
    @lsx c, 0, STR.H, r, s
   else if x eq sh
    @lsx c, 1, LDR.SH, r, s
   else
    'Invalid:' x
   end if
   syntax 1
  \}
  match =0 :c r=,s, ?s p \{ ; ldr:c
   @ls c, 1, 0, r, s
   syntax 1
  \}
  if.syntax 0
   @ldr p
  end if
}

macro @str [p] {
 common
  syntax 0
  match :x:c r=,s, p \{ ; str:x:c
   if x eq b
    @ls c, 0, 1, r, s
   else if x eq h
    @lsx c, 0, STR.H, r, s
   else
    'Invalid:' x
   end if
   syntax 1
  \}
  match =0 :c r=,s, ?s p \{ ; str:c
   @ls c, 0, 0, r, s
   syntax 1
  \}
  if.syntax 0
   @str p
  end if
}

;;;;;;;;;;;;;;; LOAD/STORE MULTIPLE ;;;;;;;;;;;;;;

; [CCCC/100P/USWL/RNXX/REGISTERSXXXXXXX]

; P  - Pre-post? Add/subtract offset before
;      (P=1) or after (P=0) transfer
; U  - Up/down. Add (U=1) or subtract offset
; S  - Load PSR or force user mode? 1/0
; W  - Write-back address to base? 1/0
; L  - Load? 1/0

; example: @ldm r0, r1,r2,r3

; [1110/100P/USWL/0000/0000000000001110]
;            1000  r0              321

macro @lsm op, b, [r] {
 common ?rs=0
 forward ?rs=?rs or (1 shl r) ; ?rs|=r
 common @arm (0Eh shl 28) or \
  (b shl 16) or (op shl 20) or ?rs
}

; @ldm/@stm = ldmia/stmdb or ldmfd/stmfd
; full descending stack. !=write-back

macro @ldm r, [p] { common @lsm 89h, r, p }
macro @stm r, [p] { common @lsm 90h, r, p }

macro @ldm! r, [p] { common @lsm 8Bh, r, p }
macro @stm! r, [p] { common @lsm 92h, r, p }

;;;;;;;;;;;;;;;;;;; PUSH + POP ;;;;;;;;;;;;;;;;;;;

; example: @push r0-r3, r5, r6, r7, v7-v8, @lr
; output:  push r0-r3, r5-r7, v7-v8, lr

macro @pp o, c, [p] {
 common
  local r, rs
  r=0
  rs=0
 forward
  syntax 0
  match a-b, p \{
   verify.r a, b
   if a>b
    'Invalid range:' a-b
   end if
   r=a
   while r<=b
    if rs and (1 shl r)<>0
     'Duplicate register in:' a-b
    end if
    rs=rs or (1 shl r)
    r=r+1
   end while
   syntax 1
  \}
  if.syntax 0
   verify.r p
   if rs and (1 shl p)<>0
    'Duplicate register:' p
   end if
   rs=rs or (1 shl p)
  end if
 common
  @arm ((c shl 28) or (@sp shl 16) \
   or (o shl 20) or rs)
}

macro @push [p] { common @pp 92h, C.al, p }
macro @pop [p]  { common @pp 8Bh, C.al, p }

macro @pushv { @push v1-v8, @lr }
macro @popv  { @pop v1-v8, @pc }

macro @test.pp {
 @push r0-r3, r5, r6, r7, v7-v8, @lr
 @pop r0-r3, r5, r6, r7, v7-v8, @pc
}

;;;;;;;;;;;;;;; DATA + ARITHMETIC ;;;;;;;;;;;;;;;;

; 31-28   25 24-21 20 19-16 15-12 987654/3210
; [CCCC/00/I/OPCODE/S/RNXX/RDXX/OPERAND2/XXXX]

;         /I=0: SHIFT R        /IIIIIIII/RMXX/
;         /I=1: SHIFT I        /SHXX/IIIIIIII/

; @mov r0, r1
; @cmp r0, r2
; @adds r0, r1, r2
; @sub:gt r0, r1, r2
; @bics:mi r1, r2, r3, asr r4

numeric it.*,\
 and, eor, sub, rsb, add, adc, sbc, rsc,\
 tst, teq, cmp, cmn, orr, mov, bic, mvn

numeric it.*,\
 ands, eors, subs, rsbs, adds, adcs, sbcs, rscs,\
 tsts, teqs, cmps, cmns, orrs, movs, bics, mvns

; create "data processing" instruction...

macro @dp it, s {
 macro @#it [p] \{
 \common
  local im
  im=0
  syntax 0
  if it in <tst,teq,cmp,cmn,mov,mvn,\
    tsts,teqs,cmps,cmns,movs,mvns>
   match a=,b=,sh, p \\{
    match x y, sh \\\{
     if ?not x in <lsl,lsr,asr,ror>
      'Operand 3 is invalid:' x
     end if
     syntax 1
    \\\}
    if.syntax 0
     'Operand 3 is invalid'
    end if
   \\}
  end if
   syntax 0
  match =0 :x a=,b=,c=,d, \ ; Mad a, b, c, <d>
   ?s p \\{
   match sh n, d \\\{
    verify.sh sh, n
    verify.r a
    if n ?is.r ; shx r
     @arm (C.\\\#x shl 28) or \
      (it.\\\#it shl 21) or (s shl 20) or \
      (a shl 12) or (b shl 16) or c or \
      (n shl 8) or (SH.\\\#sh shl 5) or 16
    else if n ?is.i ; shx #
     @arm (C.\\\#x shl 28) or \
      (it.\\\#it shl 21) or (s shl 20) or \
      (a shl 12) or (b shl 16) or c or \
      (n shl 7) or (SH.\\\#sh shl 5)
    else
     'Unexpected:' n
    end if
    syntax 1
   \\\}
   if.syntax 0 ; Mad a, b, c, ri
    verify.r a, b, c
    if ?not c ?is.r & c ?is.i
     verify.u8 c
     im=1
    end if
    @arm (C.\\#x shl 28) or \
     (it.\\#it shl 21) or (im shl 25) or \
     (s shl 20) or (b shl 16) or \
     (a shl 12) or c
   end if
   syntax 1
  \\}
  match =0 :x a=,b=,c, \ ; Mad a, b, <c>
   ?s p \\{
   match sh n, c \\\{
    verify.sh sh, n
    verify.r a, b
    if n ?is.r ; shx r
     @arm (C.\\\#x shl 28) or \
      (it.\\\#it shl 21) or (s shl 20) or \
      (a shl 12) or (a shl 16) or b or \
      (n shl 8) or (SH.\\\#sh shl 5) or 16
    else if n ?is.i ; shx #
     @arm (C.\\\#x shl 28) or \
      (it.\\\#it shl 21) or (s shl 20) or \
      (a shl 12) or (a shl 16) or b or \
      (n shl 7) or (SH.\\\#sh shl 5)
    else
     'Unexpected:' n
    end if
    syntax 1
   \\\}
   if.syntax 0 ; Mad a, b, ri
    verify.r a, b
    if ?not c ?is.r & c ?is.i ; i
     verify.u8 c
     im=1
    end if
    @arm (C.\\#x shl 28) or \
     (it.\\#it shl 21) or (im shl 25) or \
     (s shl 20) or (b shl 16) or \
     (a shl 12) or c
   end if
   syntax 1
  \\}
  match =0 :x a=,b, ?s p \\{ ; :c r, ri
   verify.r a
   if ?not b ?is.r & b ?is.i ; i
    verify.u8 b
    im=1
   end if
   @arm (C.\\#x shl 28) or \
    (it.\\#it shl 21) or (im shl 25) or \
    (s shl 20) or (a shl 16) or \
    (a shl 12) or b
   syntax 1
  \\}
  match =0 a=,b=,c=,d, \ ; a, b, c, <d>
   ?s p \\{
   match sh n, d \\\{
    verify.sh sh, n
    verify.r a, b, c
    if n ?is.r ; shx r
     @arm (C.al shl 28) or \
      (it.\\\#it shl 21) or (s shl 20) or \
      (a shl 12) or (b shl 16) or c or \
      (n shl 8) or (SH.\\\#sh shl 5) or 16
    else if n ?is.i ; shx #
     verify.u5 n
     @arm (C.al shl 28) or \
      (it.\\\#it shl 21) or (s shl 20) or \
      (a shl 12) or (b shl 16) or c or \
      (n shl 7) or (SH.\\\#sh shl 5)
    else
     'Unexpected:' n
    end if
    syntax 1
   \\\}
   if.syntax 0 ; a, b, c, ri
    verify.r a, b, c
    if ?not c ?is.r & c ?is.i
     verify.u8 c
     im=1
    end if
    @arm (C.al shl 28) or \
     (it.\\#it shl 21) or (im shl 25) or \
     (s shl 20) or (b shl 16) or \
     (a shl 12) or c
   end if
   syntax 1
  \\}
  match =0 a=,b=,c, ?s p \\{ ; a, b, <c>
   match sh n, c \\\{
    verify.sh sh, n
    verify.r a
    if n ?is.r ; shx r
     @arm (C.al shl 28) or \
      (it.\\\#it shl 21) or (s shl 20) or \
      (a shl 12) or (a shl 16) or b or \
      (n shl 8) or (SH.\\\#sh shl 5) or 16
    else if n ?is.i ; shx #
     @arm (C.al shl 28) or \
      (it.\\\#it shl 21) or (s shl 20) or \
      (a shl 12) or (a shl 16) or b or \
      (n shl 7) or (SH.\\\#sh shl 5)
    else
     'Unexpected:' n
    end if
    syntax 1
   \\\}
   if.syntax 0 ; a, b, ri
    verify.r a, b
    if ?not c ?is.r & c ?is.i
     verify.u8 c
     im=1
    end if
    @arm (C.al shl 28) or \
     (it.\\#it shl 21) or (im shl 25) or \
     (s shl 20) or (b shl 16) or \
     (a shl 12) or c
   end if
   syntax 1
  \\}
  match =0 a=,b, ?s p \\{ ; a, b
   verify.r a
   verify.o b
   if ?not b ?is.r & b ?is.i
    verify.u8 b
    im=1
   end if
   @arm (C.al shl 28) or \
    (it.\\#it shl 21) or (im shl 25) or \
    (s shl 20) or (a shl 16) or \
    (a shl 12) or b
   syntax 1
  \\}
  verify @\#i
 \}
}

macro @dp [p] {
forward
 @dp p, 0
 @dp p#s, 1
}

; create 512 instructions:

; 32 (16*2 add/s) * 16 conditions each =
; 512 total variations. "add:c" condition
; syntax avoids writing 512 macros!

@dp and, eor, sub, rsb, add, adc, sbc, rsc,\
 tst, teq, cmp, cmn, orr, mov, bic, mvn

@cmp fix @cmps ; automatic
@cmn fix @cmns
@tst fix @tsts
@teq fix @teqs

; test dp instructions...

macro @test.dp {
 @mov r7, r7     ; a=b
 @and r5, 0FFh   ; a=a&c
 @eor r5, r6, 15 ; a=b^c
 @sub r5, r6, r7 ; a=b-c
 @rsb r5, r6, r7 ; a=c-b
 @add r5, r6, r7 ; a=b+c
 @adc r5, r6, r7 ; a=b+c
 @sbc r5, r6, r7 ; a=b-c
 @rsc r5, r6, r7 ; a=c-b
 @tst r5, r6     ; a&b?
 @teq r5, r6     ; a&b?
 @cmp r5, r6     ; a=b?
 @cmn r5, r6     ; a=-b?
 @orr r5, r6, r7 ; a=b|c
 @bic r5, r6, r7 ; a=b&~c
 @mvn r5, r6     ; a=-b
}

macro @test.dpx {
 @add r5, r6, lsl r7        ; a=b<<c
 @add r5, r6, lsl 7         ; a=b<<i
 @add r0, r3, r5, lsr r7    ; a=b+(c>>>d)
 @adds r0, r3, r5, lsr 7    ; a=b+(c>>>i)
 @add:ne r0, r1, asr r7     ; ne? a=(b>>c)
 @adds:lt r0, r1, asr 7     ; lt? a=(b>>i)
 @add:gt r0, r3, r5, ror r7 ; gt? a=b+(c<>>d)
 @adds:mi r0, r3, r5, ror 7 ; mi? a=b+(c<>>7)
}

macro @inc r { @adds r, 1 }
macro @dec r { @subs r, 1 }

macro @neg r { @rsbs r, 0 }
macro @not r { @mvns r, r }

macro @abs r { ; absolute value
 @teq r, 0     ; if a<0, a=0-a
 @rsbs:mi r, 0
}

;;;;;;;;;;;;;;;;;;; SATURATION ;;;;;;;;;;;;;;;;;;;

; [CCCC/0001/QQQQ/RNXX/RDXX/0000/0101/RMXX]

; add, subtract, double, with 32BIT saturation.
; for packed 8/16BIT saturating arithmetic,
; see PACKING (Ctrl+F)

macro @qsat name, o {
 verify.cpu ARM.v5TE
 macro @#name a, b, c \{
  verify.r a, b, c
  @arm 0E1000050h or (o shl 20) \
   or (a shl 12) or b or (c shl 16)
 \}
}

@qsat qadd, 0
@qsat qsub, 2
@qsat qdadd, 4
@qsat qdsub, 6

; [CCCC/0110111/NNNNN/RDXX/IIIII/S/01/RNXX]

; saturate to bit position with optional
; shift before

macro @xsat name, o {
 macro @#name a, n, b, s \{
  verify.cpu ARM.v6
  verify.r a, b
  if s eq ; register
   @arm 0E6000010h or (o shl 16) \
    or (a shl 12) or b
  else
   match sh n, s \\{ ; shift
    if name eq ssat
     if n<1 | n>32
      'Shift # must be 1-32'
     end if
    else if name eq usat
     if n<0 | n>31
      'Shift # must be 0-31'
     end if
    end if
    if sh eq asr
     @arm 0E6001850h or (o shl 16) \
      or (a shl 12) or b
    else if sh eq lsl
     @arm 0E6001810h or (o shl 16) \
      or (a shl 12) or b
    else
     'Shift must be asr/lsl #'
    end if
    syntax 1
   \\}
  end if
  verify
 \}
}

@xsat ssat, 0AEh
@xsat usat, 0EFh

macro @test.sat {
 @qadd r3, r5, r7
 @qsub r3, r5, r7
 @qdadd r3, r5, r7
 @qdsub r3, r5, r7
 @ssat r1, 15, r5
 @ssat r1, 15, r5, asr 12
 @ssat r1, 15, r5, lsl 12
 @usat r1, 15, r5
 @usat r1, 15, r5, asr 12
 @usat r1, 15, r5, lsl 12
}

;;;;;;;;;;;;;;;;;;;; MULTIPLY ;;;;;;;;;;;;;;;;;;;;

; [CCCC/0000000/A/S/RDXX/RNXX/RSXX/1001/RMXX]

; multiply: 32*32

macro @mul a, b, c {
 verify.r a, b
 if c eq
  @arm 0E0000090h or (a shl 16) or b \
   or (a shl 8)
 else
  verify.r c
  @arm 0E0000090h or (a shl 16) or b \
   or (c shl 8)
 end if
}

macro @muls a, b, c {
 verify.r a, b
 if c eq
  @arm 0E0100090h or (a shl 16) or b \
   or (a shl 8)
 else
  verify.r c
  @arm 0E0100090h or (a shl 16) or b \
   or (c shl 8)
 end if
}

macro @mx4 name, o {
 macro @#name a, b, c, d \{
  if name eq umaal
   verify.cpu ARM.v6
  else if name eq mls
   verify.cpu ARM.v6T2
  end if
  verify.r a, b, c, d
  @arm 0E0000090h or (o shl 20) or \
   (a shl 12) or (b shl 16) or \
   c or (d shl 8)
 \}
}

; multiply + accumulate or subtract:
; 32*32+32 or 32*32-32

@mx4 mla, 2
@mx4 mls, 6

; un/signed multiply 32BIT with 64BIT
; result or accumulate

@mx4 umull, 8
@mx4 smull, 0Ch
@mx4 umlal, 0Ah
@mx4 smlal, 0Eh

; unsigned multiply 64BIT + accumulate

@mx4 umaal, 4

; signed 16BIT b/t multiply + 32BIT/64BIT
; accumulate. xy = b=bottom, t=top

macro @smulxy name, o {
 macro @#name a, b, c \{
  verify.cpu ARM.v5TE
  verify.r a, b, c
  @arm 0E1600000h or (o shl 4) or (b) \
   or (a shl 16) or (c shl 8)
 \}
}

macro @smlaxy name, o {
 macro @#name a, b, c, d \{
  verify.cpu ARM.v5TE
  verify.r a, b, c, d
  @arm 0E1000000h or (o shl 4) or b \
   or (a shl 16) or (c shl 8) or (d shl 12)
 \}
}

macro @smlalxy name, o {
 macro @#name a, b, c, d \{
  verify.cpu ARM.v5TE
  verify.r a, b, c, d
  @arm 0E1400000h or (o shl 4) or \
   (a shl 12) or (b shl 16) or c \
   or (d shl 8)
 \}
}

@smulxy smulbb, 8
@smulxy smultt, 0Eh
@smulxy smulbt, 0Ch
@smulxy smultb, 0Ah

@smlaxy smlabb, 8
@smlaxy smlatt, 0Eh
@smlaxy smlabt, 0Ch
@smlaxy smlatb, 0Ah

@smlalxy smlalbb, 8
@smlalxy smlaltt, 0Eh
@smlalxy smlalbt, 0Ch
@smlalxy smlaltb, 0Ah

; dual signed 16BIT multiply with addition
; or subtraction of products + 32BIT/64BIT
; accumulate and optional exchange of halves

macro @smlxd name, o {
 macro @#name a, b, c, d \{
  verify.cpu ARM.v6
  verify.r a, b, c, d
  @arm 0E7000000h or (o shl 4) or \
   (a shl 16) or b or (c shl 8) \
   or (d shl 12)
 \}
}

macro @smlxld name, o {
 macro @#name a, b, c, d \{
  verify.cpu ARM.v6
  verify.r a, b, c, d
  @arm 0E7400000h or (o shl 4) or \
   (a shl 12) or (b shl 16) or c \
   or (d shl 8)
 \}
}

macro @smuxd name, o {
 macro @#name a, b, c \{
  verify.cpu ARM.v6
  verify.r a, b, c
  @arm 0E700F000h or (o shl 4) or \
   (a shl 16) or b or (c shl 8)
 \}
}

@smlxd smlad, 1
@smlxd smlsd, 5

@smlxld smlald, 1
@smlxld smlsld, 5

@smuxd smuad, 1
@smuxd smusd, 5

@smuxd smuadx, 3
@smuxd smusdx, 7

; signed most significant 32BIT multiply
; with optional accumulate or subtract

macro @smmul a, b, c {
 verify.cpu ARM.v6
 verify.r a, b, c
 @arm 0E751F010h or (a shl 16) \
  or b or (c shl 8)
}

macro @smmla a, b, c, d {
 verify.cpu ARM.v6
 verify.r a, b, c, d
 @arm 0E7510010h or (a shl 16) or \
  b or (c shl 8) or (d shl 12)
}

macro @smmls a, b, c, d {
 verify.cpu ARM.v6
 verify.r a, b, c, d
 @arm 0E75100D0h or (a shl 16) or \
  b or (c shl 8) or (d shl 12)
}

; signed multiply wide 32x16 top/bottom

macro @smulx name, o {
 verify.cpu ARM.v5TE
 macro @#name a, b, c \{
  verify.r a, b, c
  @arm 0E1200000h or (o shl 4) or \
   (a shl 16) or b or (c shl 8)
 \}
}

macro @smlax name, o {
 verify.cpu ARM.v5TE
 macro @#name a, b, c, d \{
  verify.r a, b, c, d
  @arm 0E1200000h or (o shl 4) or \
   (a shl 16) or b or (c shl 8) or \
   (d shl 12)
 \}
}

@smulx smulwb, 0Ah
@smulx smulwt, 0Eh

@smlax smlawb, 8
@smlax smlawt, 0Ch

macro @test.mul {
 @mul r0, r1, r5
 @mla r1, r3, r5, r7
 @mls r1, r3, r5, r7
 @umull r1, r3, r5, r7
 @smull r1, r3, r5, r7
 @umlal r1, r3, r5, r7
 @smlal r1, r3, r5, r7
 @umaal r1, r3, r5, r7
 @smulbb r1, r3, r5
 @smultt r1, r3, r5
 @smulbt r1, r3, r5
 @smultb r1, r3, r5
 @smlabb r1, r3, r5, r7
 @smlatt r1, r3, r5, r7
 @smlabt r1, r3, r5, r7
 @smlatb r1, r3, r5, r7
 @smlalbb r1, r3, r5, r7
 @smlaltt r1, r3, r5, r7
 @smlalbt r1, r3, r5, r7
 @smlaltb r1, r3, r5, r7
 @smlad r1, r3, r5, r7
 @smlsd r1, r3, r5, r7
 @smlald r1, r3, r5, r7
 @smlsld r1, r3, r5, r7
 @smuad r1, r3, r5
 @smusd r1, r3, r5
 @smuadx r1, r3, r5
 @smusdx r1, r3, r5
 @smulwb r1, r3, r5
 @smulwt r1, r3, r5
 @smlawb r1, r3, r5, r7
 @smlawt r1, r3, r5, r7
}

; fast multiply r0 by common constant

macro @mul3  { @adds r0, r0, lsl 1 }
macro @mul5  { @adds r0, r0, lsl 2 }

macro @mul10 {
 @mov r0, r0, lsl 1  ; r0=(r0<<1)+(r0<<2)
 @adds r0, r0, lsl 2
}

;;;;;;;;;;;;;;;;;;; DIVISION ;;;;;;;;;;;;;;;;;;;;;

; un/signed 32BIT divide

if.cpu ARM.v7R

macro @xdiv name, x {
 verify.cpu ARM.v7R
 macro @#name a, b, c \{
  verify.r a, b, c
  @arm 0E700F010h or (x shl 20) or \
   (a shl 16) or b or (c shl 8)
 \}
}

@xdiv sdiv, 1
@xdiv udiv, 3

macro @test.div {
 @sdiv r1, r3, r5
 @sdiv r3, r5, r7
 @udiv r1, r3, r5
 @udiv r3, r5, r7
}

; emulate division if CPU < ARM.v7R.
; designed to be expanded once inside
; of a function with parameters...

else

macro @udiv {           ; r0/r1
 local a, b
 @mov r2, r0
 @mov r3, r1
 @cmp r3, r2, lsr 1     ; while
 a:                     ; divisor<(n*2)
  @mov:ls r3, r3, lsl 1 ; *2 if lower/same
  @cmp r3, r2, lsr 1    ; /2
 @bls a
 @mov r0, 0
 b:
  @cmp r2, r3           ; subtract only
  @sub:hs r2, r2, r3    ; if carry (hs=cs)
  @adc r0, r0           ; *2+C
  @mov r3, r3, lsr 1    ; /2
  @cmp r3, r1           ; while > divisor
 @bhs b
 @mov r1, r2            ; remainder
}

macro @idiv {           ; r0/r1
 @push @10
 @mov @10, r0
 @mov r2, r1
 @abs r0                ; get absolute
 @abs r1                ; values
 @udiv                  ; divide
 @tst r2, r2, lsl 31    ; if sign
 @rsb:ne r0, 0          ; negate
 @tst @10, @10, lsl 31
 @rsb:ne r0, 0
 @pop @10
}

macro @test.div {
 @udiv
 @sdiv
}

end if

; fast division by 10. r0/10

macro @div10 {
 @ldi r1, 1999999Ah    ; r1=((2^32)/10)+1
 @sub r0, r0, lsr 30   ; r0=r0-(r0>>>30)
 @umull r2, r0, r1, r0 ; r0=r1*r0
}

; with remainder in r1

macro @div10r {
 @mov r3, r0           ; dividend
 @div10
 @mov r1, r0, lsl 1    ; multiply by 10:
 @add r1, r1, lsl 2    ; r1=(r0<<1)+(r1<<2)
 @rsb r1, r3           ; r1=r3-r1
}

;;;;;;;;; BIT FIELD INSERT/CLEAR/EXTRACT ;;;;;;;;;

; BFI:  [CCCC/0111/110/MSBXX/RDXX/LSBXX/001/RNXX]
; BFC:  [CCCC/0111/110/MSBXX/RDXX/LSBXX/001/1111]
; SBFX: [CCCC/0111/101/MSBXX/RDXX/LSBXX/101/RNXX]
; UBFX: [CCCC/0111/111/MSBXX/RDXX/LSBXX/101/RNXX]

macro @bfv r, lsb, w {
 verify.cpu ARM.v6T2
 verify.r r
 verify.n lsb, 0, 31
 verify.n w, 1, 32-lsb
}

macro @bfx x, y, a, b, lsb, w {
 @bfv a, lsb, w
 @arm 0E7000000h or (x shl 21) or \
  (y shl 4)  or (a shl 12) or b or \
  (lsb shl 7) or ((lsb+w-1) shl 16)
}

macro @xbfx x, y, a, b, lsb, w {
 @bfv a, lsb, w
 @arm 0E7000000h or (x shl 21) or \
  (y shl 4) or (a shl 12) or b or \
  (lsb shl 7) or ((w-1) shl 16)
}

macro @bfi a, b, l, w
 { @bfx 110b, 001b, a, b, l, w }

macro @bfc r, l, w { @bfi r, 0Fh, l, w }

macro @sbfx a, b, l, w
 { @xbfx 101b, 101b, a, b, l, w }

macro @ubfx a, b, l, w
 { @xbfx 111b, 101b, a, b, l, w }

macro @test.bf {
 @bfi r1, r3, 4, 7
 @bfi r1, r3, 4, 7
 @sbfx r1, r3, 4, 7
 @ubfx r1, r3, 4, 7
}

;;;;;;;;;; SIGN/ZERO EXTEND/ADD/ROTATE ;;;;;;;;;;;

; sign or zero extend with optional add after
; and rotate before: SXT*, UXT*

; SXTB, SXTH, SXTAB, SXTAH, SXTB16, SXTAB16
; UXTB, UXTH, UXTAB, UXTAH, UXTB16, UXTAB16

; *B:    [CCCC/0110/1S10/1111/RDXX/RO/000111/RMXX]
; *H:    [CCCC/0110/1S11/1111/RDXX/RO/000111/RMXX]
; *AB:   [CCCC/0110/1S10/RNXX/RDXX/RO/000111/RMXX]
; *AH:   [CCCC/0110/1S11/RNXX/RDXX/RO/000111/RMXX]
; *B16:  [CCCC/0110/1S00/1111/RDXX/RO/000111/RMXX]
; *AB16: [CCCC/0110/1S00/RNXX/RDXX/RO/000111/RMXX]

macro verify.ror2 x, r {
 if ~ x eq
  syntax 0
  match sh n, x \{
   if sh eq ror & \
    ((n eq 0) | (n eq 8) | \
    (n eq 16) | (n eq 24))
    if n<>0
     r=n/8
    end if
   else
    'Shift must be ror 0/8/16/24'
   end if
   syntax 1
  \}
  if.syntax 0
   'Unexpected:' x
  end if
 end if
}

macro @xxt2 name, x {
 macro @#name a, b, c \{
  verify.cpu ARM.v6
  local r
  r=0
  verify.r a, b
  verify.ror2 c, r
  @arm 0E6000070h or (x shl 20) \
   or (1111b shl 16) or (a shl 12) \
   or (b) or (r shl 10)
 \}
}

macro @xxt3 name, x {
 macro @#name a, b, c, d \{
  verify.cpu ARM.v6
  local r
  r=0
  verify.r a, b, c
  verify.ror2 d, r
  @arm 0E6000070h or (x shl 20) \
   or (b shl 16) or (a shl 12) \
   or (c) or (r shl 10)
 \}
}

@xxt2 sxtb, 1010b
@xxt2 sxth, 1011b
@xxt2 sxtb16, 1000b
@xxt3 sxtab, 1010b
@xxt3 sxtah, 1011b
@xxt3 sxtab16, 1000b

@xxt2 uxtb, 1110b
@xxt2 uxth, 1111b
@xxt2 uxtb16, 1100b
@xxt3 uxtab, 1110b
@xxt3 uxtah, 1111b
@xxt3 uxtab16, 1100b

macro test.xxt {
 @sxtb r1, r3
 @sxtb r1, r3, ror 16
 @sxth r1, r3
 @sxth r1, r3, ror 16
 @sxtb16 r1, r3
 @sxtb16 r1, r3, ror 16
 @sxtab r1, r3, r7
 @sxtab r1, r3, r7, ror 16
 @sxtah r1, r3, r7
 @sxtah r1, r3, r7, ror 16
 @sxtab16 r1, r3, r7
 @sxtab16 r1, r3, r7, ror 16
 @uxtb r1, r3
 @uxtb r1, r3, ror 16
 @uxth r1, r3
 @uxth r1, r3, ror 16
 @uxtb16 r1, r3
 @uxtb16 r1, r3, ror 16
 @uxtab r1, r3, r7
 @uxtab r1, r3, r7, ror 16
 @uxtah r1, r3, r7
 @uxtah r1, r3, r7, ror 16
 @uxtab16 r1, r3, r7
 @uxtab16 r1, r3, r7, ror 16
}

;;;;;;;;;;;;;;;;;;;; PACKING ;;;;;;;;;;;;;;;;;;;;;

; 31-28   27-20 19-16 15-12 11-987/6/54/3210
; [CCCC/01101000/RNXX/RDXX/IIIIIII/T/01/RMXX]

; combine top/bottom 16BITs with optional
; shift before

macro @pkx name, t {
 macro @#name a, b, c, d \{
  local r
  r=0
  verify.cpu ARM.v6
  verify.r a, b, c
  if d eq
   if t=0
    @arm 0E6800010h or (a shl 12) or \
     (b shl 16) or (c)
   else
    @arm 0E6800010h or (a shl 12) or \
     (b) or (c shl 16)
   end if
  else
   syntax 0
   match sh n, d \\{
    if t=0
     if ?not sh eq lsl
      'Shift must be lsl'
     end if
     verify.n n, 1, 31
     @arm 0E6800010h or (a shl 12) or \
      (b shl 16) or (c) or (n shl 7)
    else
     if ?not sh eq asr
      'Shift must be asr'
     end if
     verify.n n, 1, 32
     @arm 0E6800050h or (a shl 12) or \
      (c) or (b shl 16) or (n shl 7)
    end if
    syntax 1
   \\}
   if.syntax 0
    'Shift expected:' d
   end if
  end if
 \}
}

@pkx pkhbt, 0
@pkx pkhtb, 1

macro @test.pkx {
 @pkhbt r2, r4, r7
 @pkhtb r2, r4, r7
 @pkhbt r2, r4, r7, lsl 8
 @pkhtb r2, r4, r7, asr 8
}

;;;;;;;;;;;;;;;; PACKED ARITHMETIC ;;;;;;;;;;;;;;;

; add/sub un/signed 2 16BIT or 4 8BIT with
; optional h/alve results after

;          31-28 27-20  19-16 15-12  98/7654/3210
; SADD8:  [CCCC/01100001/RNXX/RDXX/1111/1001/RMXX]
; SADD16: [CCCC/01100001/RNXX/RDXX/1111/0001/RMXX]
; SSUB8:  [CCCC/01100001/RNXX/RDXX/1111/1111/RMXX]
; SSUB16: [CCCC/01100001/RNXX/RDXX/1111/0111/RMXX]

; UADD8:  [CCCC/01100101/RNXX/RDXX/1111/1001/RMXX]
; UADD16: [CCCC/01100101/RNXX/RDXX/1111/0001/RMXX]
; USUB8:  [CCCC/01100101/RNXX/RDXX/1111/1111/RMXX]
; USUB16: [CCCC/01100101/RNXX/RDXX/1111/0111/RMXX]

; SHADD8:  [CCCC/01100011/RNXX/RDXX/1111/1001/RMXX]
; SHADD16: [CCCC/01100011/RNXX/RDXX/1111/0001/RMXX]
; SHSUB8:  [CCCC/01100011/RNXX/RDXX/1111/1111/RMXX]
; SHSUB16: [CCCC/01100011/RNXX/RDXX/1111/0111/RMXX]

; UHADD8:  [CCCC/01100111/RNXX/RDXX/1111/1001/RMXX]
; UHADD16: [CCCC/01100111/RNXX/RDXX/1111/0001/RMXX]
; UHSUB8:  [CCCC/01100111/RNXX/RDXX/1111/1111/RMXX]
; UHSUB16: [CCCC/01100111/RNXX/RDXX/1111/0111/RMXX]

macro @xas [name, x, y] {
forward
 macro @#name a, b, c \{
  verify.cpu ARM.v6
  verify.r a, b, c
  @arm1 al, 0110b, x, b, a, 1111b, y, c
 \}
}

@xas sadd8,1,9, sadd16,1,1,\
 ssub8,1,0Fh, ssub16,1,7, uadd8,5,9,\
 uadd16,5,1, usub8,5,0Fh, usub16,5,7,\
 shadd8,3,9, shadd16,3,1, shsub8,3,0Fh,\
 shsub16,3,7, uhadd8,7,9, uhadd16,7,1,\
 uhsub8,7,0Fh, uhsub16,7,7

; un/signed add+subtract or subtract+add
; with exchange and optional halving

; SASX, SSAX, SHASX, SHSAX
; UASX, USAX, UHASX, UHSAX

@xas sasx,1,3, ssax,1,5, shasx,3,3,\
 shsax,3,5, uasx,5,3, usax,5,5,\
 uhasx,7,3, uhsax,7,5

; unsigned sum of absolute differences with
; optional accumulate

macro @usad8 a, b, c {
 verify.cpu ARM.v6
 verify.r a, b, c
 @arm1 al, 0111b, 1000b, a, 1111b, c, 1, b
}

macro @usada8 a, b, c, d {
 verify.cpu ARM.v6
 verify.r a, b, c, d
 @arm1 al, 0111b, 1000b, a, d, c, 1, b
}

; SSAT16, USAT16

macro @xat [name, x, y] {
forward
 macro @#name a, b, c \{
  verify.cpu ARM.v6
  if b ?is.r
   'Operand 2 must be immediate'
  end if
  verify.r a, c
  if x eq 10
   @arm1 al, 0110b, x, b-1, a, 1111b, y, c
  else
   @arm1 al, 0110b, x, b, a, 1111b, y, c
  end if
 \}
}

@xat ssat16,10,3, usat16,0Eh,3

; QASX, QSAX, UQASX, UQSAX

@xas qasx,2,3, qsax,2,5, uqasx,6,3, uqsax,6,5

; QADD8, QADD16, QSUB8, QSUB16
; UQADD8, UQADD16, UQSUB8, UQSUB16

@xas qadd8,2,9, qadd16,2,1, qsub8,2,15,\
 qsub16,2,7, uqadd8,6,9, uqadd16,6,1,\
 uqsub8,6,15, uqsub16,6,7

macro @test.xat {
 @sadd8 r1, r3, r5
 @sadd16 r1, r3, r5
 @ssub8 r1, r3, r5
 @ssub16 r1, r3, r5
 @uadd8 r1, r3, r5
 @uadd16 r1, r3, r5
 @usub8 r1, r3, r5
 @usub16 r1, r3, r5
 @shadd8 r1, r3, r5
 @shadd16 r1, r3, r5
 @shsub8 r1, r3, r5
 @shsub16 r1, r3, r5
 @uhadd8 r1, r3, r5
 @uhadd16 r1, r3, r5
 @uhsub8 r1, r3, r5
 @uhsub16 r1, r3, r5
 @sasx r1, r3, r5
 @ssax r1, r3, r5
 @shasx r1, r3, r5
 @shsax r1, r3, r5
 @uasx r1, r3, r5
 @usax r1, r3, r5
 @uhasx r1, r3, r5
 @uhsax r1, r3, r5
 @usad8 r1, r3, r7
 @usada8 r1, r3, r5, r7
 @ssat16 r1, 8, r3
 @usat16 r1, 8, r3
 @qasx r1, r3, r5
 @qsax r1, r3, r5
 @uqasx r1, r3, r5
 @uqsax r1, r3, r5
 @qadd8 r1, r3, r5
 @qadd16 r1, r3, r5
 @qsub8 r1, r3, r5
 @qsub16 r1, r3, r5
 @uqadd8 r1, r3, r5
 @uqadd16 r1, r3, r5
 @uqsub8 r1, r3, r5
 @uqsub16 r1, r3, r5
}

;;;;;;;;;;;; SWAP, REVERSE BITS/BYTES ;;;;;;;;;;;;

; exchange register and memory

macro @swx o, a, b, c {
 verify.r a, b
 syntax 0
 match [r], c \{
  @arm o or (r shl 16) or (a shl 12) or b
  syntax 1
 \}
 verify
}

macro @swp a, b, c  { @swx 0E1000090h, a, b, c }
macro @swpb a, b, c { @swx 0E1400090h, a, b, c }

; reverse byte/bit order

macro @revx o, a, b {
 verify.cpu ARM.v6
 verify.r a, b
 @arm o or (a shl 12) or b
}

macro @rev a, b   { @revx 0E6BF0F30h, a, b }
macro @rev16 a, b { @revx 0E6BF0FB0h, a, b }
macro @revsh a, b { @revx 0E6FF0FB0h, a, b }

macro @rbit a, b  {
 verify.cpu ARM.v6T2
 verify.r a, b
 @revx 0E6FF0F30h, a, b
}

macro @test.swr {
 @swp r3, r5, [r7]
 @swpb r0, r1, [r2]
 @rev r5, r7
 @rev16 r5, r7
 @revsh r5, r7
 @rbit r5, r7
}

;;;;;;;;;;;;;;;;;;;;; STRING ;;;;;;;;;;;;;;;;;;;;;

; test string routines. inline "instrinsics"
; or expand once inside of function.
; parameters: r0-r3

; strlen(s) - get length, # characters

macro @strlen {
 local x
 @mov r2, r0
 x:
  @ldrb r1, [r0], 1 ; r1=*r0++
  @tst r1, r1       ; until 0
 @bne x
 @sub r0, r2        ; r0=r0-r2-1
 @dec r0            ; return n
}

; strcpy(a, b) - standard copy with 0 after.
; return advanced address

macro @strcpy {
 local x
 x:
  @ldrb r2, [r1], 1 ; r2=*r1++
  @strb r2, [r0], 1 ; *r0++=r2
  @tst r2, r2       ; until 0
 @bne x
 @dec r0
}

; strcat(a, b) - attach b to a

macro @strcat {
 @mov r3, r0
 @mov r4, r1
 @strlen
 @add r0, r3
 @mov r1, r4
 @strcpy
}

; strcmp(a, b) - lexical comparison

macro @strcmp {
 local x, y
 x:
  @ldrb r2, [r0], 1 ; r2=*r0++
  @ldrb r3, [r1], 1 ; r3=*r1++
  @cmp r2, r3       ; while equal
  @bne y
  @orrs r2, r3      ; and both nonzero
 @bne x
 y:
 @subs r0, r2, r3   ; return r0=r2-r3
}

; streq(a, b) - equal?

macro @streq {
 @strcmp
 @mov:eq r0, 1
 @mov:ne r0, 0
}

macro @test.strx {
 @strcat
 @streq
}    
I can convert this to standalone just by replacing the directives with runtime if/else/match/irp/s/etc.
Post 28 Feb 2014, 17:32
View user's profile Send private message Reply with quote
m3ntal



Joined: 08 Dec 2013
Posts: 296
m3ntal
A preview of my new IDE.

Custom multi-line textbox logic:
Code:
; advance to lines[caret.y]

  get p=text.go p, [caret.y]

  if [key.event]='c'         ; character?
    if [key]=0Dh             ; return, enter
      return                 ; handled above
    else.if [key]=9          ; tab. replace
      text.insert.c p,\      ; with 2 spaces
       ' ', [caret.x]
      . [caret.x]++
      . [key]=' '            ; one more
      go .insert
    else.if [key]=8          ; backspace?
      if [start.x]<>-1       ; if selection,
        .remove:             ; remove...
        delete.selection
        go .ok
      end
      if [caret.x]           ; x<>0. not begin
        . p--
        text.delete.c \      ; remove last c
         p, [caret.x]
        . [caret.x]--
      else                   ; else, x=0.
        . r0=[caret.y]       ; begin of line
        if r0=0              ; y=0? begin
          return             ; of file?
        end
        . r0--               ; move up.
        get n=text.line.w \  ; get width of
         source.code, r0     ; previous line.
        . p-2                ; delete return
        text.delete p, 2     ; characters
        . [caret.x]=n        ; x=w
        . [caret.y]--        ; up, y--
      end
    else.if [key]<20h        ; invisible
      ; ...                  ; do nothing
    else                     ; not special
      .insert:               ; insert c.
      . s=0                  ; selection?
      if [start.x]<>-1       ; if selection,
        delete.selection     ; remove.
        . s=1
      end
      text.insert.c p,\      ; insert
       [key], [caret.x]      ; character
      . [caret.x]++
      if s                   ; was there a
        text.insert.c \      ; selection?
         p, 0Dh, [caret.x]   ; return after
        . [caret.x]++
        text.insert.c \
         p, 0Ah, [caret.x]
         . [caret.x]=1
      end
      if [cursor.show]       ; hide cursor
        . [cursor.show]=0    ; while typing.
      end                    ; reappear if
    end                      ; mouse move
    .ok:
    redraw
    return
  end
  show.vga.box caret.box
  . [caret.blink]=1          ; force visible    


Description:
Filesize: 187.45 KB
Viewed: 7798 Time(s)

zide1.jpg




Last edited by m3ntal on 22 Apr 2014, 01:30; edited 1 time in total
Post 21 Apr 2014, 12:13
View user's profile Send private message Reply with quote
sid123



Joined: 30 Jul 2013
Posts: 340
Location: Asia, Singapore
sid123
well if you don't mind can you give a link to runtime "IF" macros.
Post 21 Apr 2014, 12:44
View user's profile Send private message Reply with quote
m3ntal



Joined: 08 Dec 2013
Posts: 296
m3ntal
sid123: Can't. On Android phone. The Buddha example contains the latest release of LANGUAGE.INC for X86.
Post 22 Apr 2014, 01:34
View user's profile Send private message Reply with quote
m3ntal



Joined: 08 Dec 2013
Posts: 296
m3ntal
Z-IDE default theme. LQ Preview

Notice "Definition" on the popup menu. User can click any keyword/identifier and go straight to the macro or function.


Description:
Filesize: 47.45 KB
Viewed: 7708 Time(s)

zide3.gif


Post 26 Apr 2014, 03:01
View user's profile Send private message Reply with quote
m3ntal



Joined: 08 Dec 2013
Posts: 296
m3ntal
Z-IDE SideBar: In the upper left corner: View Library, Resources (Images, Fonts, Etc), Utilities.

Library is a collection of bookmarks. Each name links to a macro or function inside of a source file or a "class DOCUMENT" with text, images and text/code. Right click to Arrange > Name, Logical, Frequency. Default is the logical order that it would be defined with the lowest level being Language, Memory, Array, Text. Frequency arranges subjects by how often they are accessed.
Code:
Language
  Variables, Types, Sizes
  Arithmetic, Operators
  Constants, Powers
  Text, Strings
  If Expressions
  Get, Try, Catch
  Loops: For, While, Repeat, etc
  Objects, Structures, Members
  Functions, Parameters, Locals
  Arrays, Objects: a[i], s->m
  Pointer Arithmetic: *p++
FASM
  Equates: a equ b
  Macro: macro, struc, rept
  restore, purge, restruc
  Constants: i=1
  Defines: define
  if, else, eq/type
  while, repeat, for
  common, forward, reverse
  Iterate: irp/s
  match
  include, file
  load, store
Imports
  Manual Import Table
  Import Macro
  ARM Imports, Exports
Memory
  Allocate, Destroy
  Copy, Set, Zero
  Bits: Get, Set, Extract
  Align, Power of 2
  Read, Write
  ARM Linux Memory
Dynamic Array
  Create, Size, Index
  Expand, Reduce
  Insert, Remove, Replace
  Zero, Erase
  Shift, Exchange
  Sort Numbers & Text
  Arrange Objects By X
  Randomize
  Encrypt
Text, String
  Lookup Tables: Types
  Get Length, # Characters
  Copy Until Zero
  Attach; Concencate
  Compare, Equal
  Search, Find
  Count # Lines, Characters
  Begins or Ends With?
  Convert to Upper/lowercase
  Expand, Prefix, Enclose
  Insert, Delete
  Align; Limit
  Text Array Search
  Number Conversions
  Print Formatted Text
  Skip/Copy While/Until Type
  ARM Text Operations
Parse, Expression
  Source & Token
  Skip/Copy While/Until Type
  Keywords
  Syntax Errors
  Define Names, Labels
  Get Token
  Identify Token
  Evaluate Expression
  Convert Infix 2 RPN
  Optimize RPN
  Convert RPN 2 ASM
  Convert Code 2 HTML
  ARM Parse, Token
Time, Date
  UTC: Universal Time
  Get Time & Date, Parse
  Set Timer Event
  X86 Instruction Timing
  ARM Linux Get Time
  Raspberry PI Timer IRQ
File I/O
  Open, Create, Close
  Seek, Tell
  Read & Write
  Load & Save Entire File
  Copy, Rename, Delete
  Parse File, Path, Ext
  Directory: Get, Set, Create
  Search: Find First, Next
  Attributes: Time, Date
  Information Structures
  Log: Write Debug Message
  ARM Angel Semi-Hosting
  ARM Linux File I/O
Box
  Get, Set, Make
  Movement, Visibility
  Alignment, Center
  Nudge, Bump, Spin
  Detect Collision
Color
  Standard Colors
  Get/Set RGB/BGR X
  Mix: Alpha Blend
  Lightness, Color
  Grayscale, Invert
  8/12BPP Palette Viewer
Drawing, Graphics
  Access VGA
  Clear Screen
  Clipping
  Pixels, Lines, Boxes
  Scanlines, Bitmaps
  Gradients: Fade, Shade
  Draw Bar/Control
  ARM PL110 Color LCD
  ARM Portable Graphics
  ARM Raspberry PI Graphics
  ARM Linux Frame Buffer
  ARM RiscOS Frame Buffer
  ARM Windows Mobile GDI
  ARM GameBoy Advance
Images
  Image Structure
  Create: Get/Set Pixels
  Draw + Transparency
  Load .BMP
  Size, Invert, Rotate
  Adjust Lightness, Color
  Invert, Convert Grayscale
  ARM Portable Image
Fonts
  Font Structure
  Free Font Bitmaps
  Get/Set Font Style/Color
  Load Font/s
  Get Text Size: W, H
  Draw Character + Text
  Draw with Alignment
  Create Text Box + Align
  Draw Caption, Button
  Draw Source Code
  ARM Portable Font
Console
  Structure, Set Address
  Write Text, String, NL
  Write Numbers: D, H, B
  Load, Save
Utility
  ASCII Table
  Number Converter
  Palette Viewer
  Convert IMAGE/BMP
  ARMv7 Disassembler
Input, Devices
  Keyboard
  Mouse
  Gamepad
Sound
  Generic PlaySound
  Initialize DirectSound
  Load WAV, Play Sound
Advanced
  I32 Machine Code Macros
  Create PE EXE Manually
  Write PE Win32 Executable
  ELF Executable Template
  Magic-ARM Assembler
  ARMv7 Disassembler
  ARM Vector Floating Point
  Java Bytecode Assembler
  Dynamic Virtual Machine
  MOS 6502 Assembler
  Z80 Disassembler
  Motorola 68K Examples    


Description: ZDS System Icons. LQ Preview
Filesize: 74.69 KB
Viewed: 7707 Time(s)

zdsi.gif


Post 26 Apr 2014, 03:04
View user's profile Send private message Reply with quote
m3ntal



Joined: 08 Dec 2013
Posts: 296
m3ntal
ZIDE Menus

For higher resolutions, 1024W-1920W. Low-level interfaces. Pure CPU logic and drawing. Every single pixel is processed by the CPU. No OS/Windows/Linux specific calls (Example: GetDC, SelectObject). Fast and responsive. New show.vga.box only displays a section of the VGA/buffer memory resulting in minimal CPU usage. Unlike previous code, this does not redraw the entire screen every mouse move. Interfaces should only redraw and/or update small sections of the screen that are effected by the cursor and controls. EZ menu:

Code:
;;;;;;;;;;;;;;;;;;;;;; MENU ;;;;;;;;;;;;;;;;;;;;;;

integer show.menu, menu.select

numeric MENU.*, NONE, POP,\
 FILE, EDIT, CODE, UTILITY, HELP

macro MENU [p] {
  common
   local i
   i=1
  forward
   match a==b, p \{
    integer a\#.menu.id=i
    BOX a\#.menu.box
    ARRAY a\#.icon.images[IMAGE]
    text a\#.menu.t(16)=b
    i=i+1
   \}
   verify
}

macro load.menu.icons [name] {
  for i=0 to name#.icon.files.$
    @ name#.icon.images[+]
    . r1=i, r1=[name#.icon.files+r1*4]
    try load.image.t r0, r1
  endl
}

macro draw.menu name {
  draw.box.s name#.menu.box, BLACK
  . [name#.menu.id]=-1
  for i=0 to name#.menu.ta.$
    . r0=[name#.menu.box.x], r0+48, x=r0
    . r0=[name#.menu.box.y], r1=i, r1*32
    . r0+r1, y=r0
    . r0=i, r0=[name#.menu.ta+r0*4], p=r0
    make.text.box p, box
    . [box.w]=[name#.menu.box.w]
    move.box box, [name#.menu.box.x], y
    if [name#.menu.id]=-1
      if.select box
        draw.shade 'v', box, ROYAL.BLUE, BLUE
        draw.outline box, BLUE
        . [name#.menu.id]=i
      end
    end
    . r0=y, r0+4
    draw.text p, x, r0
    @ p=name#.icon.images[i]
    . r0=[name#.menu.box.x], r0+8, x=r0
    . r0=y, r0+4
    draw.image p, x, r0
  endl
  draw.outline name#.menu.box, GRAY
}

macro draw.menu.name name {
  set.font.color WHITE
  . r0=[name#.menu.id]
  if [menu.select]=r0
    set.font.color 03377FFh
  end
  draw.text.b name#.menu.t, box
  if.select box
    . select=[name#.menu.id]
  end
  move.box.r box
}

macro open.menu name, x, y, w {
  . r0=[name#.menu.id]
  if [show.menu]<>r0
    . [show.menu]=r0, [name#.menu.id]=-1
    move.box name#.menu.box, x, y
    . [name#.menu.box.w]=w
    . r0=name#.menu.ta.$, r0*32, r0+4
    . [name#.menu.box.h]=r0
    set.cursor arrow.cursor
    show.vga.box name#.menu.box
  end
}

; example usage:

MENU pop='', file='File', edit='Edit',\
 code='Code', utility='Utility', help='Help'

; ...

. show=[show.menu]
if show=MENU.POP
  draw.menu pop
else.if show=MENU.FILE
  draw.menu file
else.if show=MENU.EDIT
  draw.menu edit
else.if show=MENU.CODE
  draw.menu code
else.if show=MENU.UTILITY
  draw.menu utility
else.if show=MENU.HELP
  draw.menu help
end    


Description:
Filesize: 130.71 KB
Viewed: 7629 Time(s)

zide_menus.gif


Post 30 Apr 2014, 13:55
View user's profile Send private message Reply with quote
m3ntal



Joined: 08 Dec 2013
Posts: 296
m3ntal
NEW Z-IDE VIDEO PREVIEW. AMAZING!

Legal: Z language+library is (C) and released under the revised BSD license. For examples and previews like this, I do a "poor man's copyright" by sending myself CD and/or printed copies of them in sealed envelopes.


Description: Z-IDE Video. LQ. To view, click YouTube link above.
Filesize: 22.09 KB
Viewed: 7276 Time(s)

z-ide-video.jpg


Post 10 May 2014, 07:15
View user's profile Send private message Reply with quote
m3ntal



Joined: 08 Dec 2013
Posts: 296
m3ntal
Ideas for class E-BOOK/DOCUMENT:
Code:
;;;;;;;;;;;;;;;;;;;; BOOK.INC ;;;;;;;;;;;;;;;;;;;;

; create.book book
; load.book book, name
; draw.book book
; set.page book, n
; set.page.size book, w, h
; scroll.page book, d, n
; destroy.book book

; book; array of pages

class BOOK
 integer id, type, x, y, w, h
 text name(128), author(128)
 IMAGE cover
 ARRAYS pages
endc ?book

; page; array of elements

class PAGE
 integer id, type, x, y, w, h
 text name(128)
 ARRAYS elements
 COLOR color, font.color,\
  link.color, vlink.color
endc ?page

; element of a page

class ELEMENT
 integer tag,\    ; TYPE.ELEMENT
  type, state,\   ; ET.*, ES.*
  x, y, w, h      ; location=&box
 integer a, j     ; alignment, justify
 integer nx, ny   ; nudge
 STYLE style      ; font.p, colors, etc
endc ?element

numeric ET.*, ALIGN, RETURN, BOX, TEXT,\
 BUTTON, CODE, EDIT, LINK, IMAGE

powers ES.*, VISIBLE, ACTIVE, FOCUS,\
 HIGH, SELECT, CHANGE, DISABLED

; box element

class E.BOX
 inherit ELEMENT
endc ?e.box

; text element

class E.TEXT
 inherit E.BOX
 void t
endc ?e.text

; button element

class E.BUTTON
 inherit E.TEXT
endc ?e.button

; code element

class E.CODE
 inherit E.TEXT
 integer n, maximum,\
  n.lines, line.n
endc ?e.code

; edit element

class E.EDIT
 inherit E.CODE
 integer caret.x, caret.y,\
  start.x, start.y,\
  end.x, end.y
 boolean blink, show.caret
endc ?e.edit

; link element

class E.LINK
 inherit E.TEXT
 text name(128), name2(128)
 integer page.n, line.n
endc ?e.link

; image element

class E.IMAGE
 inherit IMAGE, E.BOX
 IMAGE backup
 COLOR line.color
 integer line.w
endc ?e.image

; EXAMPLE .BOOK SCRIPT

; name='MY BOOK'
; page.color=WHITE

; <t5>TITLE</t5>
; <t4>Subject</t4>

; <t2>
; Description...
; </t2>

; <c>
; mov eax, ecx
; </c>

; <l=www.google.com>Visit Google</l>

; <t2>Visit page 5: <l='PAGE5'>CLICK HERE</l>
; </t2>

; <image='name.bmp'>    
Z-IDE Subjects+Items:
Code:
texts library.bar.ta[]=\
 'Array', 'Box', 'Color', 'Console', 'Control',\
 'Cursor', 'Draw', 'Executable', 'Expression',\
 'File', 'Font', 'Icon', 'Image', 'Input',\
 'Interface', 'Language', 'Memory', 'Parse',\
 'Sprite', 'Sound', 'Text', 'Time' 

integer any.open,\
 select.subject=-1, select.item=-1

; SUBJECT+ITEM

class SUBJECT
  integer state, n
  text title(32)
  ; ...            ; ITEMS[n]
endc ?subject

class ITEM
  integer type, state
  void link.p
  text name(32), title(32)
endc ?item

macro _SUBJECT s, [link.p, type, name, title] {
 common
  local n
  n=0
 forward
  n=n+1
 common
  match a==b, s \{      ; subject...
   a:
   dd 0                 ; 1/0, open/close
   dd n                 ; # items
   @@: db b, 0          ; subject.title(32)
   times \
    32-($-@b) db 0
  \}
 forward                ; items array
  dd type, 0            ; appears after...
  dd link.p
  @@: db name, 0        ; item.name(32)
  times 32-($-@b) db 0
  @@: db title, 0       ; item.title(32)
  times 32-($-@b) db 0
 common
  ; ...
}

; pointers to subjects + items

align 4

library.subjects: dd \
 array.subject, box.subject, color.subject,\
 control.subject, cursor.subject,\
 draw.subject, file.subject, font.subject,\
 icon.subject, image.subject, input.subject,\
 interface.subject, language.subject,\
 memory.subject, sound.subject,\
 system.subject, text.subject, time.subject

N.LIBRARY.SUBJECTS=($-library.subjects)/4

; example subject

_SUBJECT file.subject='File',\
 FILE.INC, 'f', 'open', 'Open, Create, Close',\
 FILE.INC, 'f', 'seek', 'Seek, Tell',\
 FILE.INC, 'f', 'read', 'Read & Write',\
 FILE.INC, 'f', 'load.file',\
  'Load/Save Entire File',\
 FILE.INC, 'f', 'copy.file',\
  'Copy, Rename, Delete',\
 FILE.INC, 'f', 'extract.path',\
  'Parse File, Path, Ext',\
 FILE.INC, 'f', 'set.directory',\
  'Directory: Get, Set, New',\
 FILE.INC, 'f', 'find.first',\
  'Search: Find First, Next',\
 FILE.INC, 'f', 'get.file.attributes',\
  'Attributes: Time, Date',\
 FILE.INC, 's', 'FILE.TAG',\
  'Information Structures',\
 FILE.INC, 'f', 'log',\
  'Log: Write Debug Message'  

; get subject address by index of
; pointer array

function get.subject, i
  . r0=library.subjects, r1=i, r0=[r0+r1*4]
endf

; get item address. s=subject index,
; i=item index

function get.item, s, i
  get.subject s
  . r0+SUBJECT.$, r1=ITEM.$, r1*i, r0+r1
endf

; get item text address

function get.item.text, s, i
  get.item s, i
  . r0+?item.title
endf

; get total # items in list including
; subject folders

function get.n.items
  locals p, i, n, ns,\
   ni, t, state
  . p=library.subjects    ; pointer array
  . ns=N.LIBRARY.SUBJECTS ; # subjects
  . n=0                   ; iterate through
  for i=0 to ns           ; subjects...
    get.subject i         ; s=subject address
    . ni=[?subject.n+r0]  ; # items
    . r1=\
     &[?subject.title+r0] ; title: 'Draw'
    . t=r1
    . r1=\
     [?subject.state+r0]  ; 1/0=open/close,
    . state=r1            ; expand/collapse.
    . n++                 ; +1 for subject
    if state              ; if open/expanded
      . r0=ni, n+r0       ; add # items
    end                   ; in subject
  endl
endf n

; get greatest item.title length to
; auto adjust side.bar.w

function get.item.max
  locals p, i, n, ns,\
   j, ni, t, state
  . ns=N.LIBRARY.SUBJECTS  ; # subjects
  . n=0                    ; iterate through
  for i=0 to ns            ; subjects...
    get.subject i          ; s=subject address
    . ni=[?subject.n+r0]   ; # items
    . r1=\
     &[?subject.title+r0]  ; title: 'Draw'
    . t=r1
    . r1=\
     [?subject.state+r0]   ; 1/0=open/close,
    . state=r1             ; expand/collapse.
    text.n t               ; get title length
    if r0>n                ; maximum?
      . n=r0
    end
    if state               ; iterate through
      for j=0 to ni        ; items...
        get.item.text i, j ; get text[j]
        text.n r0          ; length
        if r0>n            ; maximum?
          . n=r0
        end
      endl
    end
  endl
endf n    
Control Class:
Code:
; create.control control, type
; enable.control control
; disable.control control
; set.control.state control, state
; set.control.style control, style
; set.control.graphics control, graphics
; set.control.justify control, justify
; set.control.text control, text
; set.control.colors color, fc, lc
; set.control.box control, box
; get.control.box control, box
; move.control control, x, y
; size.control control, w, h
; set.control control, x, y, w, h
; load.control control, file
; draw.control control
; update.control control
; input.control control
; destroy.control control 

class CONTROL 
 integer \
  tag, id,\     ; TYPE.CONTROL, #
  type, state,\ ; CT.*, CS.*
  x, y, w, h,\  ; &box=location/size
  a, j,\        ; alignment, justify
  nx, ny        ; nudge

 void text.p    ; text, image, style
 void image.p   ; or 0 if unused
 void style.p   ; font.p, colors, etc

 void \
  pointer,\ ; this
  create!,\ ; control.create()
  text!,\   ; control.text('text')
  enter!,\  ; control.enter(x,y)
  leave!,\  ; control.leave(x,y)
  move!,\   ; control.move(x,y)
  size!,\   ; control.size(w,h)
  load!,\   ; control.load('file')
  draw!,\   ; control.draw()
  update!,\ ; control.update()
  input!,\  ; control.input(device,event,id)
  destroy!  ; control.destroy()
endc ?control  


?control.box fix ?control.x
?this fix ?control.pointer

; control types

numeric CT.*, NONE,\
 FRAME, WINDOW, BOX, SCRIPT, PICTURE,\
 ITEM, BUTTON, TOOLBAR, MENU, SCROLL,\
 TEXTBOX, EDITBOX, CODEBOX,\
 DROPBOX, LISTBOX, MESSAGE, INPUT

; control styles

powers CS.*,\
 VISIBLE, ENABLED, ACTIVE, DRAW,\
 MOVEABLE, SIZABLE, FOCUS,\
 HIGH, SELECT, CHANGE

CS.DEFAULT=CS.VISIBLE+CS.ENABLED\
 +CS.ACTIVE+CS.DRAW

; control.function(this, ...)

macro callct control, f, [p] {
 common
  . r0=control
  if [?control.#f+eax]
    pushr p
    push [?control.pointer+eax]
    call [?control.#f+eax]
  end
}

; define events

macro define.control name, [p] {
 forward
  . [?control.#p#!+eax]=!#p#.#name
}    
Expression parser written in C (TinyCC+GCC):
Code:
// EVALUATE CONSTANT EXPRESSION

#include <stdio.h>
#include <stdlib.h>

#define EXAMPLE "1+2*3"

#define and &&
#define or ||

#define isa(c) ((c>='A' and c<='Z') \
 or (c>='a' and c<='z') or c=='_')
#define isn(c) (c<='9' and c>='0')
enum { NAME, NUMBER, SYMBOL };

int error_n;
#define error(why) \
 printf("\nError: %s\n\n", why), error_n++

char *stream=EXAMPLE, token[256],
 type, last_type, value, depth;

int next();
void term(int *), factor(int *), atom(int *);

int main() {
  int v;
  printf("Expression: %s\n", stream);
  error_n=0, depth=0;
  next();
  term(&v);
  if (depth!=0)
   { error("Mismatched ()'s"); return; }
  if (!error_n)
    printf("Result: %d\n\n", v);
  return 0;
}

// add, subtract

void term(int *v) {
  int rv, c;
  factor(v);
  while ((c=*token)=='+' or c=='-') {
    if (!next())
     { error("Value expected"); return; }
    factor(&rv);
    if (c=='+') (*v)+=rv;
    else if (c=='-') (*v)-=rv;
  }
}

// multiply, divide

void factor(int *v) {
  int rv, c;
  atom(v);
  while ((c=*token)=='*' or c=='/') {
    if (!next())
     { error("Value expected"); return; }
    atom(&rv);
    if (c=='*') (*v)*=rv;
    else if (c=='/') (*v)/=rv;
  }
}

// get value

void atom(int *v) {
  if (error_n)
   return;
  if (*token=='(') {
    next();
    term(v);
    if (*token!=')')
     { error(") expected"); return; }
    next();
  }
  else {
    next();
    *v=value;
  }
}

// copy token and advance

int next() {
  int i;
  if (type and last_type==type)
   { error("Syntax"); return 0; }
  last_type=type;

  while (*stream==' ' or
    *stream=='\t') stream++;
  if (!*stream) return 0;
  if (*stream=='(') depth++;
  if (*stream==')') depth--;

  if (isa(*stream)) {        // NAME
    for (i=0; isn(*stream);
     token[i++]=*stream++);
    token[i]=0;
    type=NAME;
    return 1;
  }
  if (isn(*stream)) {        // NUMBER
    for (i=0; isn(*stream);
     token[i++]=*stream++);
    token[i]=0;
    value=atoi(token);
    type=NUMBER;
    return 1;
  }
  token[0]=*stream++;        // SYMBOL
  token[1]=0;
  type=SYMBOL;
  return 1;
}    


Last edited by m3ntal on 28 May 2014, 23:58; edited 1 time in total
Post 18 May 2014, 22:06
View user's profile Send private message Reply with quote
m3ntal



Joined: 08 Dec 2013
Posts: 296
m3ntal
New Java bytecode disassembler. Source not available, doesn't support the official .CLASS specification, but there are some general functions below. Example output:
Code:
class Test {

  constants(#32) {
    #1: Text = "Code"
    #2: Text = "<init>"
    #3: Text = "main"
    #4: Text = "([Ljava/lang/String;)V"
    #5: Class: #6
    #6: Text = "Test"
    #7: Method: #8:#10
    #8: Class: #9
    #9: Text = "java/lang/Object"
    #10: Prototype: #2:#11
    #11: Text = "()V"
    #12: Field: #13:#15
    #13: Class: #14
    #14: Text = "java/lang/System"
    #15: Prototype: #16:#17
    #16: Text = "out"
    #17: Text = "Ljava/io/PrintStream;"
    #18: Method: #19:#21
    #19: Class: #20
    #20: Text = "java/io/PrintStream"
    #21: Prototype: #22:#23
    #22: Text = "println"
    #23: Text = "(Ljava/lang/String;)V"
    #24: Method: #25:#27
    #25: Class: #26
    #26: Text = "java/lang/Integer"
    #27: Prototype: #28:#29
    #28: Text = "toString"
    #29: Text = "(I)Ljava/lang/String;"
    #30: String: #3
    #31: String: #4
    #32: Integer
  }

Access: public super 
This: #5
Super: #8
Interfaces: 0
Fields: 0
Methods: 2

Method: 1. Name: #2. Access: #1. Type: #11
Stack: 8. Locals: 8. Size: 5

  public void Test() {
    0: aload_0
    1: invokespecial #7        ; Object:<init>
    4: return
  }

Method: 2. Name: #3. Access: #9. Type: #4
Stack: 8. Locals: 8. Size: 15

  public static void main(String[]) {
    0: getstatic #12           ; System:out
    3: dup
    4: ldc #30                 ; main
    6: invokevirtual #18       ; PrintStream:println
    9: ldc #31                 ; ([Ljava/lang/String;)V
    11: invokevirtual #18      ; PrintStream:println
    14: return
  }

}    
Java utility functions for encoding/decoding .CLASS. Think of these as ideas and algorithms.
Code:
; get address of constant # in pool.
; global void constant.pool.p points
; to the beginning

function j.go.constant, n
  locals \
   i, p, q, type
  . p=[constant.pool.p]
  if p=0
    return 0
  end
  . r0=[n.constants]
  if n>r0
    return 0
  end

  ; iterate through constants until
  ; index #n...

  for i=0 to n
    . r0=p, q=r0, r1=>[r0]
    . type=r1, p++

    ; get index size and advance pointer
    ; (indices are not linear, they are
    ; variable-sized structures)

    if type=JC.TEXT
      . r0=p, r1=>[r0], r1<<8
      . r2=>[r0+1], r1|r2, p+r1
    end
    . r1=type
    if r1<j.constant.types.$
      . r2=[j.constant.sizes+r1*4]
      . p+r2
    end
  endl
endf q

; get/return constant type at index #n

function j.get.constant.type, n
  j.go.constant n
  . r0=>[r0]
endf

; get t=constant text/string value
; at index #n

function j.get.constant, t, n
  locals p, q, type
  . r0=t, byte [r0]=0
  .a:
  try p=j.go.constant n
  . r1=>[r0], type=r1, p++
  if type<>JC.TEXT
    if type<>JC.STRING
      return 0
    end
  end
  . r0=p, r1=>[r0], r1<<8
  . r2=>[r0+1], r1|r2, n=r1, p+2
  if type=JC.STRING
    go .a
  end
  memory.copy t, p, n
  . r0=t, r0+n, byte [r0]=0
endf 1

; get class:method or member

function j.get.constant.cm, t, n
  locals p, q, type
  . r0=t, byte [r0]=0
  try p=j.go.constant n
  . r1=>[r0], type=r1, p++
  . r0=p, r1=>[r0], r1<<8
  . r2=>[r0+1], r1|r2, n=r1, p+2 ; u2 class index
  call !j.get.class.i, t, n
  call !j.get.class, t7, t
  text.attach.c t7, ':'
  . r0=p, r1=>[r0], r1<<8
  . r2=>[r0+1], r1|r2, n=r1, p+2 ; u2 name+type
  j.go.constant n
  . r0++, r1=>[r0], r1<<8
  . r2=>[r0+1], r1|r2, n=r1, p+2
  j.get.constant t6, n
  text.attach t7, t6
  text.copy t, t7
endf 1

; get type name from 'C'. example:

; j.get.type t, 'D' ; t='double'

; all of these "t,c/s" functions
; return t='text' or 0 if error...

text j.types.c='VBCDFIJLSZ['

textai j.types,\
 JT.NONE='none', JT.VOID='void',\
 JT.BYTE='byte', JT.CHAR='char',\
 JT.DOUBLE='double', JT.FLOAT='float',\
 JT.INT='int', JT.LONG='long',\
 JT.CLASS='class', JT.SHORT='short',\
 JT.BOOL='bool', JT.ARRAY='array'

function j.get.type, t, c
  . r0=t, byte [r0]=0
  text.find j.types.c, c
  if false
    return 0
  end
  . r0-j.types.c, r0++
  . r0=[j.types+r0*4]
  text.copy t, r0
endf 1

; get class name from s/pecial format.
; no L prefix, optional Wink after. returns
; length of original name - ;

; example: s='java/lang/String;'
; result: t='String'

function j.get.class, t, s
  locals n, c
  . r0=t, byte [r0]=0
  . n=0, c=1, r0=s      ; get length
  while c               ; until 0, ; or )
    . r1=>[r0], c=r1
    if c=0
      go .out
    else.if c=';'
      go .out
    else.if c=')'
      go .out
    end
    . r0++, n++
  endw
  .out:
  text.find.last s, '/' ; find last /
  if true               ; java/x/Name;
    . r0++, s=r0        ; past /
  end
  text.copy t, s
  text.find t, ')'      ; advance to )
  if true
    . byte [r0]=0       ; remove
  end
  text.find t, ';'      ; advance to ;
  if true
    . byte [r0]=0       ; remove
  end
endf n

; get class name by #index

function j.get.class.i, t, n
  locals p
  try p=j.go.constant n
  get1
  get2
  try j.get.constant t, n
endf 1

; get return type from s/pecial format.
; s must begin with (

; example: s='(I)V' (void name(int))

; j.get.return t, s ; t='void'

function j.get.return, t, s
  . r0=t, byte [r0]=0
  . r0=s
  if byte [r0]<>'('
    return 0
  end
  if byte [r0+1]=')'
    if byte [r0+2]=0
      return 1
    end
  end
  text.find s, ')'
  if false
    return 0
  end
  . r0++, r0=>[r0]
  j.get.type t, r0
endf 1

; get parameters text (a,b,c) from
; s/pecial format. example:

; s='(II)V' (void name(int,int))

; j.get.parameters t, s ; 'int,int'

function j.get.parameters, t, s
  locals p, i, c,\
   q, n, a, x
  . r0=t, byte [r0]=0
  text.find s, '('      ; advance to (
  if false
    return 0
  end
  . r0++, p=r0          ; past (
  . i=0, n=0, c=1
  while c
    . r0=p, p++         ; get next c
    . r0=>[r0], c=r0
    if c=0
      go .out
    end
    if c=')'            ; end ) or ;
      go .out
    end
    if c=';'
      ; go .out         ; ... ?
    else
      if n              ; not first
        text.attach.c \ ; , after
         t, ','
      end
    end
    . a=0
    if c='['            ; is array? [
      . a=1             ; yes
      . r0=p, p++       ; get next c
      . r0=>[r0]        ; no multi [s
      . c=r0
    end
    if c<>'L'           ; not class?
      j.get.type it, c  ; I=int, C=char
      text.n it
      . p+r0
    else                ; class name
      j.get.class \
       t4, p
      . x=r0            ; length
      text.attach \
       it, t4
      . r0=x, p+r0
    end
    . n++
    text.attach t, it   ; a,b,c
    if a                ; array?
      text.attach.c \
       t, '['
      text.attach.c \
       t, ']'
    end
    . x=0, q=t          ; remove
    @@:                 ; beginning
    . r0=q              ; whitespace
    . r1=>[r0], c=r1    ; 2-DO: text.trim
    if r1=' '
      . x++, q++
      go @b
    else.if r1=9
      . x++, q++
      go @b
    end
    if x
      text.delete t, x
    end
    . i++
  endw
  .out:
  text.find.last t, ';'
  if true
    . byte [r0]=0
  end
  if n
    . n--
  end
endf n    
EXTREME EZ R/W, I/O. putx/getx to read/write numbers+text to/from memory or file. What could be easier?
Code:
putt t              ; text
putt a1, a2, a3     ; 2+ parameters
puts t              ; string +NL after
putz t              ; string +0, binary
putc '*'            ; character/s
putc 'Z', '=', '1'  ; 2+ parameters
putr                ; return, NL
put1 i              ; byte
put2 i              ; integer 16BIT
put4 i              ; integer 32BIT
putn x, y, n        ; same (put4)
putf f, a, b, c     ; format (print/f)    
All getx/putx needs to know is the mode (memory, console, file), endian (for 16BIT+), source and destiny addresses, sizes and maximums (allocation size or memory end). putx can use a custom memory allocator (CPU-portable) and it can be as simple as: add p, size | cmp p, memory.end | jae .error.

Universal Assembler Formats
Code:
Just: use system. For each system, there is a *.INC
that defines the format:

use emu   ; QEMU=Default (For embedded systems)
use linux ; Linux for RPI+ (For serious development)
use wrt   ; Windows RT/Surface (Don't have one yet)
use rpi   ; Raspberry PI bare-metal
use risc  ; RiscOS for RPI+
use wm    ; Windows CE/Mobile (text t='Unicode')
use gba   ; Gameboy Advance (Fast learning, testing)

format defines the cpu:model, OS and extension ('ExT'/'eXt').
Default settings are ARM-1176JZ-F QEMU Versatile PB with
PL110 LCD controller.

format emu              ; default settings
format emu arm:1176JZ_F ; same

format linux
format arm linux      ; same
format arm:1176JZ_F \ ; same (long way)
 linux elf as 'ELF'
format linux as 'elf' ; same but lowercase .elf
format linux as ''    ; same but omit .ELF extension

format arm:v7            ; QEMU ARMv7+VFP/NEON
format arm:cortex_a9 emu ; same

Note: Selecting an OS automatically overrides CPU settings.
Selecting a CPU sets lower-level attributes like endian
and address size.    


Last edited by m3ntal on 28 May 2014, 23:43; edited 1 time in total
Post 28 May 2014, 05:04
View user's profile Send private message Reply with quote
m3ntal



Joined: 08 Dec 2013
Posts: 296
m3ntal
Motorola 68k example
Code:
;;;;;;;;;;;;;;;;;;; EASY 68K ;;;;;;;;;;;;;;;;;;;;;

; template for Easy68k assembler+simulator.
; search google. supports file I/O, mouse/key
; input and graphics

; to test, press F9 or click "Assemble" (right
; arrow). in the message box that appears,
; click Execute. in Sim68k, press F9 or "Run"

; warning: in some older assemblers, certain
; lines MUST be indented by 2+ spaces or it
; will display an error: "Invalid opcode"

; see Help > Simulator I/O and "Jimmy Mardells
; 68000 reference"

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

START ORG $1000
    
  lea text, a1   
  move #14, d0  ; task=14, display text at a1
  trap #15
   
SIMHALT

; <functions here>

text dc.b 'EXAMPLE', 0

  END     START

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

START ORG $1000
  
  bsr test_memset
  bsr newl
  bsr test_memcpy
  bsr newl
  bsr test_strcpy
  bsr newl
  bsr test_strlen

SIMHALT

; push/pop all except a7/sp.
; movem.l=load/store multiple

pusha macro
  movem.l d0-d7/a0-a6, -(a7)
  endm

popa macro
  movem.l (a7)+, d0-d7/a0-a6
  endm

; memcpy(a0, a1, d0)

memcpy:   
  cmp.l #4, d0         ; d0<4?
  blo mc8
  movem.l d0, -(a7)    ; push d0
  lsr.l #2, d0         ; n/4
  mc32:
   move.l (a1)+, (a0)+ ; (u32) *a0++=*a1++
   sub.l #1, d0        ; until 0
  bne mc32
  movem.l (a7)+, d0    ; pop d0
  and.l #3, d0         ; modulo 4
  mc8:
   move.b (a1)+, (a0)+ ; (u8) *a0++=*a1++
   sub.l #1, d0        ; until 0
  bne mc8
  mce:
  rts                  ; return

; memset8(a0, d0, d1)
  
memset8:   
  cmp.l #0, d1         ; d0=0?
  beq ms8e
  ms8:
   move.b d0, (a0)+    ; (u8) *a0++=d0
   sub.l #1, d1        ; until 0
  bne ms8
  ms8e:
  rts                  ; return

; memset16(a0, d0, d1)
  
memset16:
  cmp.l #0, d1         ; d0=0?
  beq ms16e
  ms16:
   move.w d0, (a0)+    ; (u16) *a0++=d0
   sub.l #1, d1        ; until 0
  bne ms16
  ms16e:
  rts                  ; return

; memset32(a0, d0, d1)
  
memset32:
  cmp.l #0, d1         ; d0=0?
  beq ms32e
  ms32:
   move.l d0, (a0)+    ; (u32) *a0++=d0
   sub.l #1, d1        ; until 0
  bne ms32
  ms32e:
  rts                  ; return

; strlen(a0); return in d0

strlen:
  move.l #0, d0
  sl:
   move.b (a0)+, d1    ; (u8) d1=*a0++
   add.l #1, d0        ; d0++
   cmp.b #0, d1        ; until 0
  bne sl
  sub.l #1, d0         ; d0--
  rts                  ; return

; strcpy(a0, a1)

strcpy:
  move.b (a1)+, d0     ; (u8) d0=*a1++
  move.b d0, (a0)+     ; *a0++=d0
  cmp.b #0, d0         ; until 0   
  bne strcpy           ; copy
  rts                  ; return

; new line

newl:
  lea crlf, a1         ; new line
  move #14, d0         ; task=14, display text at a1
  trap #15             ; irq
  rts                  ; return

; testing...

test_memcpy:
  lea buffer, a0       ; a0=&buffer
  lea text, a1         ; a1=&text
  move.l #11, d0       ; d0=#
  bsr memcpy           ; copy
  lea buffer, a1       ; a1=&buffer
  move #14, d0         ; task=14, display text at a1
  trap #15             ; irq
  rts                  ; return

test_memset:
  lea buffer, a0       ; a0=&buffer ; initialize
  move.l #0, d0        ; d0=value
  move.l #128, d1      ; d1=#
  bsr memset8
  lea buffer, a0       ; a0=&buffer ; copy 7 A's
  move.l #$41, d0      ; d0=value
  move.l #7, d1        ; d1=#
  bsr memset8
  lea buffer, a1       ; a1=&buffer
  move #14, d0         ; task=14, display text at a1
  trap #15             ; irq
  rts                  ; return
  
test_strlen:
  lea text, a0         ; a0=&text
  bsr strlen           ; length
  move.l d0, d1        ; d1=d0
  move #3, d0          ; task=3, display number in d1
  trap #15             ; irq
  rts                  ; return

test_strcpy:
  lea buffer, a0       ; a0=&buffer
  lea text, a1         ; a1=&text
  bsr strcpy           ; copy
  lea buffer, a1       ; a1=&buffer
  move #14, d0         ; task=14, display text at a1
  trap #15             ; irq
  rts                  ; return

  ORG   (*+3)&-4       ; align

buffer ds.b 128
number dc.l 1234567
text dc.b 'EXAMPLE123', 0
crlf dc.b $0D, $0A, 0

  END     START

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; example function with parameters

      offset  4+4     ; parameters
sum   ds.l    1 
n2    ds.l    1 
n1    ds.l    1 
      org     *       ; end offset

adder:
  link a0, #0         ; create stack frame
  move.l d0, -(sp)    ; save d0
  move.l (n1,a0), d0  ; access n1 parameter
  add.l (n2,a0), d0   ; add n2 parameter
  move.l d0, (sum,a0) ; store result
  move.l (sp)+, d0    ; restore d0
  unlk a0             ; destroy stack frame
  rts    
Post 28 May 2014, 05:10
View user's profile Send private message Reply with quote
m3ntal



Joined: 08 Dec 2013
Posts: 296
m3ntal
COMPARE: Z VS FRESHLIB

Just one example:

* Z draw.box (DRAW.INC). Fast, CPU+OS portable, draws to memory VGA/buffer/matrix (use graph paper), absolute control of graphics.
Code:
function draw.box, x, y, w, h, c
  alias vga=a1, c=v1,\
   sw=v2, w=v3, h=v4,\
   pitch=a2, wb=a3
  . w=a3, sw=w, h=a4    ; save w/h
  vga.xy
  . pitch=SCREEN.PITCH  ; screen+row
  . wb=w<<1             ; w in bytes
  .repeat h             ; h # times
    . w=sw              ; reset saved
    .repeat w           ; w # times
      . (u16) *vga++=c  ; copy color
    .endr
    . vga+pitch, vga-wb ; advance
  .endr
endf    
Code:
; generates optimized ARM assembler...

000000E0 E92D5FF0 stmdb  sp!, {v1-ip,lr}
000000E4 E1A06002 mov    v3, a3
000000E8 E1A05006 mov    v2, v3
000000EC E1A07003 mov    v4, a4
000000F0 E92D000F stmdb  sp!, {a1-a4}
000000F4 E3A02000 mov    a3, 0
000000F8 E3822C05 orr    a3, a3, 500h
000000FC E0130291 muls   a4, a2, a3
00000100 E0933080 adds   a4, a4, a1, lsl 1
00000104 E3A01000 mov    a2, 0
00000108 E3811602 orr    a2, a2, 200000h
0000010C E0910003 adds   a1, a2, a4
00000110 E1A0A000 mov    v7, a1
00000114 E8BD000F ldmia  sp!, {a1-a4}
00000118 E1A0000A mov    a1, v7
0000011C E3A01000 mov    a2, 0
00000120 E3811C05 orr    a2, a2, 500h
00000124 E1A02086 mov    a3, v3, lsl 1
00000128 E3570000 cmp    v4, 0
0000012C 0A000009 beq    158h
00000130 E1A06005 mov    v3, v2
00000134 E3560000 cmp    v3, 0
00000138 0A000002 beq    148h
0000013C E0C040B2 strh   v1, [a1], 2
00000140 E2566001 subs   v3, v3, 1
00000144 EAFFFFFA b      134h
00000148 E0900001 adds   a1, a1, a2
0000014C E0500002 subs   a1, a1, a3
00000150 E2577001 subs   v4, v4, 1
00000154 EAFFFFF3 b      128h
00000158 E8BD9FF0 ldmia  sp!, {v1-ip,pc}    
* FreshLib DrawFillRect (graphics\Win32\draw.inc). Slow, GDI, Windows specific, RE-creates a brush and pen everytime, limited to Windows styles, 12 invokes to HL functions that were written in C/C++ (HL should call LL, not LL calling HL).
Code:
proc DrawFillRect, .context, .x, .y, .width, .height, .color
begin
        push    eax ebx ecx edx esi

        mov     ebx, [.context]

        mov     eax, [.color]
        bswap   eax
        ror     eax, 8
        mov     esi, eax
        invoke  CreateSolidBrush, esi
        invoke  SelectObject, [ebx+TContext.handle], eax
        push    eax

        invoke  CreatePen, PS_SOLID, 0, esi
        invoke  SelectObject, [ebx+TContext.handle], eax
        push    eax

        mov     eax, [.x]
        mov     ecx, [.y]
        add     eax, [.width]
        add     ecx, [.height]

        cmp     [.width], 1
        je      .line1
        cmp     [.height], 1
        jne     .rect

        dec     ecx
        jmp     .line

.line1:
        dec     eax
.line:
        invoke  MoveToEx, [ebx+TContext.handle], eax, ecx, 0
        invoke  LineTo, [ebx+TContext.handle], [.x], [.y]
        inc     [.x]
        invoke  LineTo, [ebx+TContext.handle],[.x], [.y]
        jmp     .free

.rect:
        invoke  Rectangle, [ebx+TContext.handle], [.x], [.y], eax, ecx

;        lea     ecx, [.x]
;        invoke  FillRect, [ebx+TContext.handle], ecx, eax
.free:
        invoke  SelectObject, [ebx+TContext.handle] ; from the stack.
        invoke  DeleteObject, eax
        invoke  SelectObject, [ebx+TContext.handle] ; from the stack.
        invoke  DeleteObject, eax
        pop     esi edx ecx ebx eax
        return
endp    
* Z: Ideas for advanced systems programmers. Ultimate library/system design provides a rock solid foundation to build upon. Only the most useful, essential features. Truly portable graphics, images, fonts. Professional, concise, well thought out. (Of course, no design is perfect and implementations can always be improved).

* FreshLib: For beginners and system-specific programmers. Style is HL macros (proc, invoke, etc) mixed with assembler. IMO, poorly designed and written, random copy and paste, unorganized, RE-writes tons of code, RE-specifies conventions (stdcall/invoke/cinvoke/exec/etc). FL is only good for reference to Windows/Linux functions.

EXTREME EZ UI/INTERFACES

See Magic-ARM examples in Non-X86 forum:
Code:
; APPLICATION TEMPLATE

include 'z.inc'

code2.font

IMAGE small.icon.i='PROJECT',\
 up.i='UP', down.i='DOWN'

ICON32 \
 new.i='NEW', project.i='PROJECT',\
 open.i='OPEN', save.i='SAVE',\
 undo.i='UNDO', cut.i='CUT',\
 copy.i='COPY', paste.i='PASTE',\
 search.i='SEARCH', code.i='CODE',\
 build.i='BUILD', execute.i='EXECUTE',\
 debug.i='DEBUG', settings.i='SETTINGS'

text title='File  Edit  Code  Create  Help'
text close.t='X', mini.t='-'

function draw.window
  WW=SCREEN.W-8
  draw.black.bar 4, 4, WW, 32  ; title
  draw.box \                   ; small icon
   8, 7, 24, 24, BLACK
  draw.outline \
   8, 7, 24, 24, GRAY
  draw.image.t \
   small.icon.i, 12, 11
  draw.text title,\            ; caption
   48, 8, WHITE
  WX=SCREEN.W-64-8             ; close 'X'
  draw.outline \
   WX, 5, 64, 30, GRAY
  TX=WX+27
  draw.text close.t,\
   TX, 7, WHITE
  WX=WX-40
  draw.outline \               ; minimize '-'
   WX, 7, 40, 30, GRAY
  WX=WX+12
  draw.text mini.t,\
   WX, 12, WHITE
  draw.shade \                 ; toolbar
   4, 34, WW, 48,\
   BLACK, GRAY25
  draw.outline \
   4, 34, WW, 48, GRAY
  WX=4
  WY=83
  WH=SCREEN.H-WY-4             ; textbox
  draw.box WX, WY,\
   WW, WH, WHITE
  WH=12
  draw.fade 4, WY, WW, WH,\    ; fade
   GRAY, WHITE
  WX=SCREEN.W-40
  draw.box WX, 83,\            ; scrollbar
   36, 393, BLACK
  draw.outline WX, 83,\
   36, 393, GRAY
  WX=WX+2
  draw.shade WX, 85,\          ; up knob
   32, 56, BLACK, GRAY
  draw.outline WX, 85,\
   32, 56, WHITE
  AX=SCREEN.W-35
  draw.image.t up.i, AX, 100   ; arrow
  draw.shade WX, 235,\         ; center knob
   32, 56, BLACK, GRAY
  draw.outline WX, 235,\
   32, 56, WHITE
  WY=SCREEN.H-56-6
  draw.shade WX, WY,\          ; down knob
   32, 56, BLACK, GRAY
  draw.outline WX, WY,\
   32, 56, WHITE
  AX=SCREEN.W-35               ; arrow
  WY=WY+16
  draw.image.t down.i, AX, WY
endf

function draw.toolbar
  IX=8
  IY=42
  draw.image.t project.i, IX, IY
  IX=IX+40
  draw.image.t new.i, IX, IY
  IX=IX+40
  draw.image.t open.i, IX, IY
  IX=IX+40
  draw.image.t save.i, IX, IY
  IX=IX+40
  draw.image.t undo.i, IX, IY
  IX=IX+40
  draw.image.t cut.i, IX, IY
  IX=IX+40
  draw.image.t copy.i, IX, IY
  IX=IX+40
  draw.image.t paste.i, IX, IY
  IX=IX+40
  draw.image.t search.i, IX, IY
  IX=IX+40
  draw.image.t code.i, IX, IY
  IX=IX+40
  draw.image.t build.i, IX, IY
  IX=IX+40
  draw.image.t execute.i, IX, IY
  IX=IX+40
  draw.image.t debug.i, IX, IY
  IX=IX+40
  draw.image.t settings.i, IX, IY
endf

main
  draw.window
  draw.toolbar
endm    
Code:
; Z-IDE DESIGN FOR ARM

include 'z.inc'

code3.font

IMAGE small.icon.i='PROJECT',\
 up.i='UP', down.i='DOWN'

ICON project.i='PROJECT',\
 open.i='FOLDER', save.i='FILE',\
 undo.i='UNDO', cut.i='CUT',\
 copy.i='COPY', paste.i='PASTE',\
 search.i='SEARCH', build.i='BUILD',\
 execute.i='EXECUTE', zoom.in.i='ZOOM_IN',\
 zoom.out.i='ZOOM_OUT'

text title='ZIDE  File  Edit  Code  Help'
text close.t='X', mini.t='-', line.n.t='#123'

source.code db \
 '; ARM Assembler: 640x480x16', 0Dh, 0Ah,\
 '', 0Dh, 0Ah,\
 'mov r0, 800000h', 0Dh, 0Ah,\
 'swi BIOS.SETUP', 0Dh, 0Ah,\
 'movne r1, r2, lsr 8', 0Dh, 0Ah,\
 'addgt r1, r2, r3, ror r4', 0Dh, 0Ah,\
 'ldr r0, [r1, 4]', 0Dh, 0Ah,\
 'swi BIOS.OPEN.FILE', 0Dh, 0Ah,\
 'mul r1, r2, r3', 0Dh, 0Ah,\
 'streq r7, [r1, r2, lsl 23]', 0Dh, 0Ah,\
 'swi BIOS.WRITE.TEXT', 0Dh, 0Ah,\
 'sublo r1, r2, asr 17', 0

function draw.toolbar
  IX=8
  IY=48
  draw.image.t project.i, IX, IY
  IX=IX+56
  draw.image.t open.i, IX, IY
  IX=IX+56
  draw.image.t save.i, IX, IY
  IX=IX+56
  draw.image.t undo.i, IX, IY
  IX=IX+56
  draw.image.t cut.i, IX, IY
  IX=IX+56
  draw.image.t copy.i, IX, IY
  IX=IX+56
  draw.image.t paste.i, IX, IY
  IX=IX+56
  draw.image.t search.i, IX, IY
  IX=IX+56
  draw.image.t build.i, IX, IY
  IX=IX+56
  draw.image.t execute.i, IX, IY
endf

function draw.window
  WW=SCREEN.W-8
  draw.black.bar 4, 4, WW, 38  ; title
  draw.box 10, 10,\            ; small icon
   24, 24, BLACK
  draw.outline \
   10, 10, 24, 24, GRAY
  draw.image.t \
   small.icon.i, 14, 14
  WX=SCREEN.W-64-8             ; close
  draw.outline \
   WX, 7, 64, 30, GRAY
  TX=WX+24
  draw.text close.t,\
   TX, 5, WHITE
  WX=WX-40
  draw.outline \               ; minimize
   WX, 7, 40, 30, GRAY
  WX=WX+12
  draw.text mini.t,\
   WX, 12, WHITE
  draw.shade 4, 40, WW, 64,\   ; toolbar
   BLACK, GRAY25
  draw.outline \
   4, 40, WW, 64, GRAY
  WX=4
  WY=104
  WH=SCREEN.H-WY-4             ; textbox
  draw.box WX, WY,\
   WW, WH, WHITE
  WH=12
  draw.fade 4, WY, WW, WH,\
   GRAY, WHITE
  draw.shade 540, 107,\        ; draw zoom
   54, 108, BLACK, GRAY
  draw.outline 540, 107,\
   54, 108, GRAY75
  draw.image.t zoom.in.i,\
   544, 112
  draw.image.t zoom.out.i,\
   544, 160
  WX=SCREEN.W-44
  draw.box WX, WY,\            ; scrollbar
   40, 373, BLACK
  WX=WX+2
  draw.shade WX, 106,\         ; up knob
   36, 56, BLACK, GRAY
  draw.outline WX, 106,\
   36, 56, WHITE
  AX=SCREEN.W-36
  draw.image.t up.i, AX, 120
  draw.shade WX, 270,\         ; center knob
   36, 56, BLACK, GRAY
  draw.outline WX, 270,\
   36, 56, WHITE
  WY=SCREEN.H-56-6
  draw.shade WX, WY,\          ; down knob
   36, 56, BLACK, GRAY
  draw.outline WX, WY,\
   36, 56, WHITE
  AX=SCREEN.W-36
  WY=WY+16
  draw.image.t down.i, AX, WY
  WX=SCREEN.W-44
  WY=104
  WH=SCREEN.H-WY-4
  draw.outline 4, WY,\
  WW, WH, WHITE
endf

main
  draw.window
  draw.text title, 48, 6, WHITE
  draw.toolbar
  draw.code source.code, 12, 108
  draw.shade 512, 438,\
   80, 34, GRAY.L, WHITE
  draw.outline 512, 438, 80, 34, GRAY75
  draw.text line.n.t, 520, 440, BLACK
endm    
Post 28 May 2014, 23:40
View user's profile Send private message Reply with quote
m3ntal



Joined: 08 Dec 2013
Posts: 296
m3ntal
ZDS/IDE EVOLUTION:
Image
Image

SOURCE PREVIEW: SUBJECTS/ITEMS/BOOKMARKS
Code:
;;;;;;;;;;;;;;;;; SUBJECTS, ITEMS ;;;;;;;;;;;;;;;;

class SUBJECT
  integer state, n
  text title(32)
  ; ...            ; ITEMS[n]
endc ?subject

class ITEM
  integer type, state
  void link.p
  text name(32), title(32)
endc ?item

macro SUBJECT s,\
 [link.p, type, name, title] {
 common
  local n
  n=0
 forward
  n=n+1
 common
  match a==b, s \{      ; subject...
   a:
   dd 0                 ; 1/0, open/close
   dd n                 ; # items
   @@: db b, 0          ; subject.title(32)
   times \
    32-($-@b) db 0
  \}
 forward                ; items array
  dd type, 0            ; appears after...
  dd link.p
  @@: db name, 0        ; item.name(32)
  times 32-($-@b) db 0
  @@: db title, 0       ; item.title(32)
  times 32-($-@b) db 0
 common
  ; ...
}

; pointers to subjects + items

align 4

library.subjects: dd \
 array.subject, book.subject,\
 box.subject, color.subject,\
 control.subject, cursor.subject,\
 draw.subject, effect.subject,\
 file.subject, font.subject, icon.subject,\
 image.subject, input.subject, interface.subject,\
 language.subject, memory.subject, parse.subject,\
 sprite.subject, sound.subject,\
 system.subject, text.subject, time.subject,\
 user.subject

N.LIBRARY.SUBJECTS=($-library.subjects)/4

text ARRAY.INC='ARRAY.INC',\
 BMP.INC='BMP.INC', BOOK.INC='BOOK.INC',\
 BOX.INC='BOX.INC', CLIP.INC='CLIP.INC',\
 COLOR.INC='COLOR.INC', CONTROL.INC='CONTROL.INC',\
 CURSOR.INC='CURSOR.INC', DRAW.INC='DRAW.INC',\
 EFFECT.INC='EFFECT.INC',\
 EXPRESSION.INC='EXPRESSION.INC',\
 FILE.INC='FILE.INC', FONT.INC='FONT.INC',\
 ICON.INC='ICON.INC', IMAGE.INC='IMAGE.INC',\
 INPUT.INC='INPUT.INC',\
 INTERFACE.INC='INTERFACE.INC',\
 LANGUAGE.INC='LANGUAGE.INC',\
 MEMORY.INC='MEMORY.INC', PARSE.INC='PARSE.INC',\
 SPRITE.INC='SPRITE.INC', SOUND.INC='SOUND.INC',\
 SYNTAX.INC='SYNTAX.INC', SYSTEM.INC='SYSTEM.INC',\
 TEXT.INC='TEXT.INC', TIME.INC='TIME.INC',\
 USER.INC='USER.INC',\
 ADVANCED.INC='.'

SUBJECT array.subject='Array',\
 ARRAY.INC, 'm', 'ARRAY', 'Create',\
 ARRAY.INC, 'f', 'array.create', 'Initialize',\
 ARRAY.INC, 'f', 'array.size', 'Allocate',\
 ARRAY.INC, 'f', 'array.index', 'Index: S*I+B',\
 ARRAY.INC, 'f', 'array.expand', 'Expand, Reduce',\
 ARRAY.INC, 'f', 'array.insert', 'Insert, Attach',\
 ARRAY.INC, 'f', 'array.remove', 'Remove, Replace',\
 ARRAY.INC, 'f', 'array.zero', 'Zero, Erase',\
 ARRAY.INC, 'f', 'array.shift', 'Shift L/R',\
 ARRAY.INC, 'f', 'array.exchange', 'Exchange',\
 ARRAY.INC, 'm', 'array.sort.n',\
  'Sort Numbers/Text',\
 ARRAY.INC, 'm', 'array.sorts.n',\
  'Arrange Objects',\
 ARRAY.INC, 'f', 'array.randomize', 'Randomize',\
 ARRAY.INC, 'f', 'array.encrypt', 'Encrypt'

SUBJECT book.subject='Book',\
 BOOK.INC, 'c', 'BOOK', 'E-Book',\
 BOOK.INC, 'c', 'PAGE', 'Page, Elements',\
 BOOK.INC, 'f', 'load.book', 'Load Book',\
 BOOK.INC, 'f', 'draw.book', 'Draw Book',\
 BOOK.INC, 'f', 'update.book', 'Update Book',\
 BOOK.INC, 'f', 'scroll.page', 'Scroll Page',\
 BOOK.INC, 'f', 'set.page.n', 'Set Page #',\
 BOOK.INC, 'f', 'set.page.size', 'Set Page Size',\
 BOOK.INC, 'f', 'search.book', 'Search 4 Text',\
 BOOK.INC, 'f', 'zoom.book', 'Zoom In/Out'

SUBJECT box.subject='Box',\
 BOX.INC, 'c', 'BOX', 'Create',\
 BOX.INC, 'f', 'move.box', 'Movement',\
 BOX.INC, 'f', 'align.box', 'Alignment',\
 BOX.INC, 'f', 'visible?', 'Visibility',\
 BOX.INC, 'f', 'collide.box', 'Collision',\
 INPUT.INC, 'f', 'select.box', 'Selection'

SUBJECT color.subject='Color',\
 SYNTAX.INC, 's', 'THEME', 'Themes',\
 COLOR.INC, '#', 'BLACK', 'Standard Colors',\
 COLOR.INC, 'f', 'rgb', 'Get/Set RGB',\
 COLOR.INC, 'f', 'mix', 'Alpha Blend',\
 COLOR.INC, 'o', 'BLACK', 'Light/Darkness',\
 COLOR.INC, 'o', 'hsl', 'Convert HSL',\
 COLOR.INC, 'o', 'hue', 'Color/Hue Shift',\
 COLOR.INC, 'o', 'light', 'In/Decrease RGB',\
 COLOR.INC, 'o', 'grayscale', 'Grayscale',\
 COLOR.INC, 'o', 'inversion', 'Invert',\
 COLOR.INC, 'o', 'channelize', 'Channelize'

SUBJECT control.subject='Control',\
 INTERFACE.INC, 0, 0, 'Interface',\
 CONTROL.INC, 'c', 'CONTROL', 'Create',\
 CONTROL.INC, 'f', 'x', 'Get/Set',\
 CONTROL.INC, 'f', 'move.control', 'Move, Size',\
 CONTROL.INC, 'f', 'update.control', 'Events',\
 CONTROL.INC, 'c', '.', 'Frame',\
 CONTROL.INC, 'c', '.', 'Caption',\
 CONTROL.INC, 'c', '.', 'Button',\
 CONTROL.INC, 'c', '.', 'Toolbar',\
 CONTROL.INC, 'c', '.', 'Scrollbar',\
 CONTROL.INC, 'c', '.', 'Menu',\
 CONTROL.INC, 'c', '.', 'Listbox',\
 CONTROL.INC, 'c', '.', 'Textbox',\
 CONTROL.INC, 'c', '.', 'Dropbox'

SUBJECT cursor.subject='Cursor',\
 CURSOR.INC, 'c', 'CURSOR', 'Create',\
 CURSOR.INC, 'f', 'load.cursor', 'Load',\
 CURSOR.INC, 'f', 'set.cursor', 'Set, Spot',\
 CURSOR.INC, 'f', 'draw.cursor', 'Draw',\
 INPUT.INC, 'v', 'mouse', 'Input'

SUBJECT draw.subject='Draw',\
 DRAW.INC, 'm', 'xy', 'Access VGA',\
 DRAW.INC, 'f', 'clear.screen', 'Clear Screen',\
 CLIP.INC, 'f', 'clip.line', 'Clipping',\
 DRAW.INC, 'f', 'draw.line', 'Pixels, Lines',\
 DRAW.INC, 'f', 'draw.box', 'Boxes',\
 DRAW.INC, 'f', 'draw.scanline', 'Scanlines',\
 DRAW.INC, 'f', 'draw.bitmap', 'Bitmaps',\
 DRAW.INC, 'f', 'draw.fade', 'Gradients',\
 FONT.INC, 'f', 'draw.c', 'Characters',\
 FONT.INC, 'f', 'draw.text', 'Text',\
 SYNTAX.INC, 'f', 'draw.code', 'Source Code',\
 FONT.INC, 'f', 'draw.time', 'Time/Date'

SUBJECT effect.subject='Effect',\
 EFFECT.INC, 'f', '.', 'Sharpen',\
 EFFECT.INC, 'f', '.', 'Blur, Motion',\
 EFFECT.INC, 'f', '.', 'Enhance',\
 EFFECT.INC, 'f', '.', 'Screen Effects'

SUBJECT file.subject='File',\
 FILE.INC, 'f', 'open', 'Open, Create, Close',\
 FILE.INC, 'f', 'seek', 'Seek, Tell',\
 FILE.INC, 'f', 'read', 'Read & Write',\
 FILE.INC, 'f', 'load.file',\
  'Load/Save Entire File',\
 FILE.INC, 'f', 'append.file',\
  'Append Data',\
 FILE.INC, 'f', 'copy.file',\
  'Copy, Rename, Delete',\
 FILE.INC, 'f', 'extract.path',\
  'Parse Name, Path, Ext',\
 FILE.INC, 'f', 'set.directory',\
  'Directory: Get, Set, New',\
 FILE.INC, 'f', 'find.first',\
  'Search: Find First, Next',\
 FILE.INC, 'f', 'get.file.attributes',\
  'Attributes: Time, Date',\
 FILE.INC, 'c', 'FILE.TAG',\
  'Information Structures',\
 FILE.INC, 'f', 'log',\
  'Log: Write Debug Message'

SUBJECT font.subject='Font',\
 SYNTAX.INC, 'c', 'THEME', 'Themes',\
 FONT.INC, 'c', 'FONT', 'Create',\
 FONT.INC, 'f', 'set.font.color', 'Set Font Color',\
 FONT.INC, 'f', 'set.font', 'Set Font Style',\
 FONT.INC, 'f', 'load.font', 'Load Font/s',\
 FONT.INC, 'f', 'text.w', 'Get Text Size',\
 FONT.INC, 'f', 'draw.c', 'Draw Character',\
 FONT.INC, 'f', 'draw.text', 'Draw Text',\
 FONT.INC, 'f', 'draw.text.a', 'Draw Aligned',\
 FONT.INC, 'f', 'make.text.box', 'Make Text Box',\
 FONT.INC, 'f', 'draw.caption', 'Draw Caption',\
 SYNTAX.INC, 'f', 'draw.code', 'Draw Source Code',\
 FONT.INC, 'f', 'draw.time', 'Draw Time/Date'

SUBJECT icon.subject='Icon',\
 ICON.INC, 'c', 'ICON', 'Create',\
 ICON.INC, 'f', 'load.icon', 'Load .BMP',\
 ICON.INC, 'f', 'draw.icon', 'Draw'

SUBJECT image.subject='Image',\
 IMAGE.INC, 'c', 'IMAGE', 'Create',\
 IMAGE.INC, 'f', 'create.image', 'Set Pixels',\
 IMAGE.INC, 'f', 'draw.image', 'Draw',\
 IMAGE.INC, 'f', 'load.image', 'Load Image',\
 IMAGE.INC, 'f', 'move.image', 'Move, Size',\
 IMAGE.INC, 'f', 'rotate.image', 'Invert, Rotate',\
 IMAGE.INC, 't', 'operation', 'Operations',\
 IMAGE.INC, 'f', 'image.effect', 'Effects',\
 IMAGE.INC, 'o', 'image.mix', 'Alpha Blend',\
 IMAGE.INC, 'o', 'image.light', 'Light/Darkness',\
 IMAGE.INC, 'o', 'image.hue', 'Color/Hue Shift',\
 IMAGE.INC, 'o', 'image.color', 'In/Decrease RGB',\
 IMAGE.INC, 'o', 'image.grayscale', 'Grayscale',\
 IMAGE.INC, 'o', 'image.inversion', 'Invert RGB',\
 IMAGE.INC, 'o', 'image.channelize', 'Channelize'

SUBJECT input.subject='Input',\
 INPUT.INC, 'm', 'if.key', 'Keyboard',\
 INPUT.INC, 'm', 'if.select', 'Mouse',\
 INPUT.INC, 'm', 'if.gamepad', 'Gamepad'

SUBJECT interface.subject='Interface',\
 CONTROL.INC, 'x', '.', 'Fonts',\
 CONTROL.INC, 'x', '.', 'Icons',\
 CONTROL.INC, 'x', '.', 'Toolbar',\
 CONTROL.INC, 'x', '.', 'Scrollbars',\
 CONTROL.INC, 'x', '.', 'Sidebar',\
 CONTROL.INC, 'x', '.', 'Menu'

SUBJECT language.subject='Language',\
 LANGUAGE.INC, 'm', 'numeric', 'Constants, Powers',\
 LANGUAGE.INC, 'm', 'BYTE', 'Variables, Types',\
 LANGUAGE.INC, 'm', 'let', 'Arithmetic, Operators',\
 LANGUAGE.INC, 'm', 'TEXT', 'Text, Strings',\
 LANGUAGE.INC, 'm', 'if', 'If Expressions',\
 LANGUAGE.INC, 'm', 'get', 'Get, Try, Catch',\
 LANGUAGE.INC, 'm', 'loop', 'Loops: For, While, Etc',\
 LANGUAGE.INC, 'm', 'function', 'Functions, Return',\
 LANGUAGE.INC, 'm', 'structure', 'Classes, Objects',\
 LANGUAGE.INC, 'm', 'let', 'Pointer Arithmetic',\
 ARRAY.INC, 'm', 'ARRAY', 'Dynamic Arrays'

SUBJECT memory.subject='Memory',\
 MEMORY.INC, 'f', 'allocate', 'Allocation',\
 MEMORY.INC, 'f', 'memory.copy', 'Copy, Set',\
 MEMORY.INC, 'm', 'get.bit', 'Bits: Get, Set',\
 MEMORY.INC, 'f', 'align.n', 'Align',\
 MEMORY.INC, 'f', 'm.read', 'Read, Write'

SUBJECT parse.subject='Parse',\
 PARSE.INC, 'v', 'source', 'Source & Token',\
 PARSE.INC, 'f', 'skip.while', 'Skip/Copy While/Until',\
 PARSE.INC, 'v', 'keywords', 'Keywords',\
 PARSE.INC, 'v', 'errors', 'Syntax Errors',\
 PARSE.INC, 'f', 'define.name', 'Define Names, Labels',\
 PARSE.INC, 'f', 'get.token','Get Token',\
 PARSE.INC, 'f', 'identify.token', 'Identify Token',\
 EXPRESSION.INC, 'f', 'valuate', 'Evaluate Expression',\
 EXPRESSION.INC, 'f', 'evaluate', 'Convert Infix 2 RPN'

SUBJECT sound.subject='Sound',\
 SOUND.INC, 'f', 'set.sound', 'Initialize',\
 SOUND.INC, 'f', 'load.sound', 'Sound Object',\
 SOUND.INC, 'f', 'load.sound', 'Load Sound',\
 SOUND.INC, 'f', 'play.sound', 'Play Sound',\
 SOUND.INC, 'f', 'load.sound', 'Get/Set Position',\
 SOUND.INC, 'f', 'load.sound', 'Adjust Volume'

SUBJECT sprite.subject='Sprite',\
 SPRITE.INC, 'c', 'SPRITE', 'Create',\
 SPRITE.INC, 't', 'adjectives', 'Adjectives',\
 SPRITE.INC, 'f', 'load.sprite', 'Load',\
 SPRITE.INC, 'f', 'draw.sprite', 'Draw',\
 SPRITE.INC, 'f', 'move.sprite', 'Move, Size',\
 SPRITE.INC, 'f', 'invert.sprite', 'Invert, Rotate',\
 SPRITE.INC, 'm', 'animate', 'Animation'

SUBJECT system.subject='System',\
 SYSTEM.INC, 'm', 'os.memory', 'Memory',\
 SYSTEM.INC, 'f', 'os.create.file', 'File',\
 SYSTEM.INC, 'f', 'os.create.vga', 'VGA',\
 SYSTEM.INC, 'f', '_window.procedure', 'Input',\
 SOUND.INC, 'f', 'set.sound', 'Sound',\
 SYSTEM.INC, 'v', '_on.event', 'Events',\
 SYSTEM.INC, 'f', '_window.procedure', 'Procedure'

SUBJECT text.subject='Text',\
 TEXT.INC, 'm', 'define.ilt', 'Lookup Tables',\
 TEXT.INC, 'f', 'n2t', 'Number Conversions',\
 TEXT.INC, 'm', 'print', 'Print Formatted Text',\
 TEXT.INC, 'f', 'text.n', 'Get Length',\
 TEXT.INC, 'f', 'text.copy', 'Copy Until Zero',\
 TEXT.INC, 'f', 'text.attach', 'Attach; Concencate',\
 TEXT.INC, 'f', 'text.compare', 'Compare, Equal',\
 TEXT.INC, 'f', 'text.find', 'Search, Find',\
 TEXT.INC, 'f', 'text.count', 'Count Appearances',\
 TEXT.INC, 'f', 'text.n.lines', 'Count # Lines',\
 TEXT.INC, 'f', 'text.begins', 'Begins/Ends With?',\
 TEXT.INC, 'f', 'text.upper', 'Convert Case',\
 TEXT.INC, 'f', 'text.expand', 'Expand, Prefix',\
 TEXT.INC, 'f', 'text.insert', 'Insert, Delete',\
 TEXT.INC, 'f', 'text.align', 'Align; Limit',\
 TEXT.INC, 'f', 'text.begins', 'Text Array Search',\
 TEXT.INC, 'f', 'text.copy.while',\
  'Skip/Copy While/Until Type'

SUBJECT time.subject='Time',\
 TIME.INC, 'm', 'start.time', 'Instruction Timing',\
 TIME.INC, 0, 0, 'UTC: Universal Time',\
 TIME.INC, 'n', 'SECOND', 'Time Constants',\
 TIME.INC, 'f', 'get.time', 'Get Time/Date',\
 TIME.INC, 'f', 'parse.time', 'Parse Time/Date',\
 FONT.INC, 'f', 'draw.time', 'Draw Time/Date',\
 SYSTEM.INC, 'm', 'os.set.timer', 'Set Timer Event'

SUBJECT user.subject='User',\
 USER.INC, 'f', '.', 'Human',\
 USER.INC, 'f', '.', 'Location',\
 USER.INC, 'f', '.', 'Contact',\
 USER.INC, 'f', '.', 'Profile',\
 USER.INC, 'f', '.', 'Create, Array',\
 USER.INC, 'f', '.', 'Load, Save Users',\
 USER.INC, 'f', '.', 'Add, Remove User',\
 USER.INC, 'f', '.', 'Arrange Users by X',\
 USER.INC, 'f', '.', 'Search Users by X'

SUBJECT advanced.subject='X Advanced',\
 0, '.', '.', 'Write I32 Machine Code',\
 0, '.', '.', 'Create PE EXE Manually',\
 0, '.', '.', 'Write PE Win32 Executable',\
 0, '.', '.', 'ELF Executable Template',\
 0, '.', '.', 'Magic-ARM Assembler',\
 0, '.', '.', 'Magic-ARM Compiler',\
 0, '.', '.', 'ARMv7 Disassembler',\
 0, '.', '.', 'Import/Export Modules',\
 0, '.', '.', 'Java Bytecode Assembler',\
 0, '.', '.', 'Java Bytecode Disassembler',\
 0, '.', '.', 'Dynamic Virtual Machine',\
 0, '.', '.', 'MOS 6502 Assembler',\
 0, '.', '.', 'MOS 6502 Emulator',\
 0, '.', '.', 'Z80 Disassembler',\
 0, '.', '.', 'Motorola 68K Examples'

; SUBJECT+ITEM functions...

; get subject address by index of pointer array

function get.subject, i
  . r0=library.subjects, r1=i, r0=[r0+r1*4]
endf

; get item address. s=subject index, i=item index

function get.item, s, i
  get.subject s
  . r0+SUBJECT.$, r1=ITEM.$, r1*i, r0+r1
endf

; get item text address

function get.item.text, s, i
  get.item s, i
  . r0+?item.title
endf

; get total # items in list including
; subject folders

function get.n.items
  locals p, i, n, ns,\
   ni, t, state
  . p=library.subjects    ; pointer array
  . ns=N.LIBRARY.SUBJECTS ; # subjects
  . n=0                   ; iterate through
  for i=0 to ns           ; subjects...
    get.subject i         ; s=subject address
    . ni=[?subject.n+r0]  ; # items
    . r1=\
     [?subject.state+r0]  ; 1/0=open/close,
    . state=r1            ; expand/collapse.
    . n++                 ; +1 for subject
    if state              ; if open/expanded
      . r0=ni, n+r0       ; add # items
    end                   ; in subject
  endl
endf n

; get greatest item.title length to
; auto adjust side.bar.w

function get.item.max
  locals p, i, n, ns,\
   j, ni, t, state
  . ns=N.LIBRARY.SUBJECTS  ; # subjects
  . n=0                    ; iterate through
  for i=0 to ns            ; subjects...
    get.subject i          ; s=subject address
    . ni=[?subject.n+r0]   ; # items
    . r1=\
     &[?subject.title+r0]  ; title: 'Draw'
    . t=r1
    . r1=\
     [?subject.state+r0]   ; 1/0=open/close,
    . state=r1             ; expand/collapse.
    text.n t               ; get title length
    if r0>n                ; maximum?
      . r0+[font.w]
      . n=r0
    end
    if state               ; iterate through
      for j=0 to ni        ; items...
        get.item.text i, j ; get text[j]
        text.n r0          ; length
        if r0>n            ; maximum?
          . n=r0
        end
      endl
    end
  endl
endf n

; draw sidebar with subjects/folders and items

function draw.side.bar
  locals i, j, w, x, y,\
   ix, iy, iw, n, t, p, s, c,\
   state, theme
  . theme=[source.theme]
  . [any.open]=NO

  . r0=[screen.h], r0-48
  set.box side.bar.box,\
   0, 48, [side.bar.w], r0
  . [clip.tx]=[side.bar.w]

  set.font.color [code.text.color]
  if [side.bar.view]=SBV.LIBRARY
    . p=library.subjects
    . n=N.LIBRARY.SUBJECTS
  else.if [side.bar.view]=SBV.PROJECT
    ; ...
  else.if [side.bar.view]=SBV.RESOURCE
    ; ...
  end

  if [show.menu]=0
  . [select.subject]=-1
  . [select.item]=-1
  end
  . x=8, y=56

  ; draw side-bar

  for i=0 to n
    . r0=p, r1=i
    . r0=[r0+r1*4], s=r0      ; s=current
    . r1=[?subject.state+r0]  ; subject
    . state=r1
    . w=[?subject.n+r0]
    . r1=&[?subject.title+r0]
    . t=r1, r1=y, r1-4
    . r2=[side.bar.w], r2-x
    set.box item.box,\
     x, r1, r2, 40

    if state                    ; expanded
      draw.image open.i, x, y
      if [show.menu]=0
        go @f
      end
    else                        ; collapsed
      draw.image close.i, x, y
      if [show.menu]=0
        @@:
        if.select item.box
          . [select.subject]=i
        end
      end
    end
    move.box.right item.box, 36
    . [item.box.w]-40
    . c=[code.color], r0=i
    if [select.subject]=r0
      draw.shade 'v',\
       item.box, ROYAL.BLUE, BLUE
      draw.outline item.box, BLUE
      . c=WHITE
    end
    set.font.color c
    . r0=x, r0+44, y+4
    draw.text t, r0, y
    . r0=[font.h],\
     r0+16, y+r0
    if state               ; open/expanded?
      . [any.open]=YES
      for j=0 to w
        . r0=x, r0+28
        draw.image \
         project.i, r0, y
        . r0=[project.i.x] ; |_ < draw
        . r0-10            ; lines on
        . r1=[project.i.y] ; icon side
        . r2=[project.i.h]
        . r2/2, r1+r2
        draw.line.h \
         r0, r1, r2, GRAY
        . r0=[project.i.x], r0-10
        . r1=[project.i.y]
        . r2=[project.i.h], r2/2
        . r1-r2, r1-8, r2*2, r2+8
        draw.line.v \
         r0, r1, r2, GRAY
        if j=0
          draw.image open.i       ; redraw
        end
        . r0=s, r0+SUBJECT.$      ; r0=current
        . r1=j, r1*ITEM.$, r0+r1  ; item
        . r1=&[?item.title+r0]
        . t=r1
        make.text.box t, item.box
        . r0=x, r0+64, r1=y, r1+4
        move.box item.box, r0, r1
        copy.box box, item.box
        . r2=[side.bar.w]
        . r2-[box.x], [box.w]=r2

        if [show.menu]=0
          if.select box           ; select
            . [select.subject]=i  ; item?
            . [select.item]=j
          end
        end
        . c=[code.color]
        . r0=i
        if [select.subject]=r0
          . r0=j
          if [select.item]=r0
            . c=[keyword.color]   ; underline
            text.n t
            . r2=r0, r2*[font.w]
            . r0=x, r0+68
            . r1=y, r1+28
            . ix=r0, iy=r1, iw=r2
            draw.line.h \
             r0, r1, r2, c
            . r0=iy, r0++
            draw.line.h \
             ix, r0, iw, c
          end
        end
        set.font.color c
        . r0=x, r0+68, r1=y, r1+4
        draw.text t, r0, r1
        . r0=[font.h], r0+16, y+r0
      endl
    end
  endl
  @@:
  . [clip.tx]=-1

  ; get scroll bar color

  if theme=ST.DEFAULT
    @@: . c=0E0E0E0h
  else.if theme=ST.STANDARD
    go @b
  else.if theme=ST.BLUE
    . c=[screen.color]
  else
    . c=BLACK
  end
endf    
Post 05 Oct 2014, 01:22
View user's profile Send private message Reply with quote
Matrix



Joined: 04 Sep 2004
Posts: 1171
Location: Overflow
Matrix
hi
cool Z-IDE

do i know you?
Post 05 Oct 2014, 03:28
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page Previous  1, 2, 3, 4  Next

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You can attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar.

Powered by rwasa.