Podarilo se mi rozsirit u Pasma sm/rem z 16bit/16bit na 28bit/12bit!
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/Automatic$ ../check_word.sh 'abc equ 0x789 PUSHDOT(0x1234567) PUSH(abc) SMDIVREM' > smaz.asm && pasmo -d smaz.asm smaz.bin
__EVAL_S16(sm/rem,0x0123,0x4567,abc)
IS_NUM __TEMP_A: 1 >(0x0123)<
IS_NUM __TEMP_B: 1 >(0x4567)<
IS_NUM __TEMP_C: 0 > (abc)<
__LINKER:>__LINKER<
__eval_op_num_xxx_pasmo({sm%},{0x4567},{abc},{0x0123})
__eval_op_num_xxx_pasmo({sm/},{0x4567},{abc},{0x0123})
.warning: Pasmo does not support 32 bit numbers and M4 does not know all values(They can only emulate 16bit/16bit without checking the range): "0x0123<<16+0x4567 abc sm/rem"
abc EQU 0789
0000:D5 PUSH DE
0001:E5 PUSH HL
0002:110805 LD DE, 0508
0005:21A726 LD HL, 26A7
Emiting raw binary from 0000 to 0007
dworkin@dw-A15:~/Programovani/ZX/Forth/Automatic$ ../check_word.sh 'abc equ 0x789 PUSHDOT(-0x1234567) PUSH(abc) SMDIVREM' > smaz.asm && pasmo -d smaz.asm smaz.bin
__EVAL_S16(sm/rem,0xFEDC,0xBA99,abc)
IS_NUM __TEMP_A: 1 >(0xFEDC)<
IS_NUM __TEMP_B: 1 >(0xBA99)<
IS_NUM __TEMP_C: 0 > (abc)<
__LINKER:>__LINKER<
__eval_op_num_xxx_pasmo({sm%},{0xBA99},{abc},{0xFEDC})
__eval_op_num_xxx_pasmo({sm/},{0xBA99},{abc},{0xFEDC})
.warning: Pasmo does not support 32 bit numbers and M4 does not know all values(They can only emulate 16bit/16bit without checking the range): "0xFEDC<<16+0xBA99 abc sm/rem"
abc EQU 0789
0000:D5 PUSH DE
0001:E5 PUSH HL
0002:11F8FA LD DE, FAF8
0005:2159D9 LD HL, D959
Emiting raw binary from 0000 to 0007
dworkin@dw-A15:~/Programovani/ZX/Forth/Automatic$
Vyzadalo si to hodne premysleni.
Prvne jsem musel vyresit jak udelat obycejne ABS u 32bitove hodnoty, pokud mate jen 16 bitovou aritmetiku bez carry a jinych priznaku.
Zni to jednoduse, ale musite si uvedomit, ze vysledek horniho slova je zavisly i na spodnim slovu a naopak.
Nakonec jsem prisel na reseni, kdy mam 2 funkce/makra podle toho zda chci vratit ve vysledku horni nebo spodni slovo v absolutni hodnote.
ABS_HI(HI,LO) = (HI>>15?~(HI+(LO=0)):HI)
kde (LO=0) je 0 pokud je spodni slovo nenulove, jinak je -1, takze i kdyz je pred tim plus tak se odcita 0 nebo 1.
Jedna se o postup kdy prevratime vsechny bity vstupu pokud ma sign nastaveny na jedna a pokud byl spodni dvoubajt nula, tak jeste odectu od horniho dvoubajtu jednicku (protoze jsme dole pretekli).
ABS_LO(HI,LO) = (HI>>15?-LO:LO)
tady me chvilku unikalo, ze znamenko je ulozene v hornim slove a resil jsem to pres __16BIT_TO_ABS.
Horsi problem byl, ze i kdyz pouziji tyhle makra na muj vzorec pro um/mod, tak potrebuji jeste nastavit spravne znamenka pro vysledky.
Napriklad to deleni ma byt zaporne, kdyz delitel a delenec maji rozdilne znamenka.
A i kdyz pasmo ma ? operator tak ten me nepomuze protoze ho musim obalit do zavorek, takze tim unarni minusko neudelam.
Mohl bych vygenerovat -1, ale Pasmo nasobi jen unsigned, takze misto otoceni znamenka vysledku bych udelal jen 0xFFFF*X.
Takze me zbyva mit vzorec 2x delsi jen kvuli jedinemu minusku?
Ne! Kdyz to nemohu nasobit -1, tak to stale mohu "ze zavorky" xorovat!
((U_A/U_B) xor (0xFFFF)) + 1
((U_A/U_B) xor (0x0000)) + 0
0xFFFF nebo 0x0000 se udela uz snadno pres (((A xor B)>>15)*0xFFFF)
a 1 nebo 0 se udela obdobne ((A xor B)>>15)
U mod casti je to jen zavisle na A, takze tam ani neni "A xor B" ale jen "A".
PS: Ty funkce jsem musel trosku vice testovat, protoze jsem to napsal dost neprehledne, snazil jsem se zjistovat zda zname nejaky vstup a podle toho nektere casti uz predpocita pomoci M4. A to se resi proste jinak, misto -1 u logickeho porovnani to dela 1, ma to jiny poradi vyhodnoceni atd. Ani ty makra radsi nebudu ukazovat... .)
Jen test pro:
__ABS20BIT_SHR_4 ...tohle melo byt pouzito pro pripad ze hornich 12 bitu je 0 nebo -1, v podstate to dela ABS(0x54321)>>4 = 0x5432
__ABS32BIT_SHR16
__ABS32BIT_AND_0xFFFF ...tohle je zaiimave tim, ze je to jediny nazev makra s malym pismenem (x).
Kód:
dworkin@dw-A15:~/Programovani/ZX/Forth/Automatic$ ./abs32_28_24_20.sh
1
2 ORG 0x8000
3
4
5 ;---- 0xFFFABCE0 --> 0x54320 --> 0x5432
6 hi1 equ 0xFFFA
7 lo1 equ 0xBCE0
8
9 ld bc,+((hi1)>>15?~((hi1)<<12+(lo1)>>4+((15& (lo1))=0)):(hi1)<<12+(lo1)>>4)
10 ld bc,+((hi1)>>15?~((hi1)<<12+3022-1):(hi1)<<12+3022)
11 ld bc,+(~(0xA000+(lo1)>>4+((15& (lo1))=0)))
12 ld bc,+21554
13
14 ;---- 0xFFFABCE0 --> 0x00054320
15
16 ld de,+((hi1)>>15?~((hi1)+((lo1)=0)):hi1)
17 ld de,+((hi1)>>15?~(hi1):hi1)
18 ld de,+(5-((lo1)=0))
19 ld de,+5
20
21 ld hl,+((hi1)>>15?-(lo1):lo1)
22 ld hl,+((hi1)>>15? 17184:48352)
23 ld hl,+(-(lo1))
24 ld hl,+17184
25
26 hi2 equ -6
27 lo2 equ -17184
28
29 ld bc,+((hi2)>>15?~((hi2)<<12+(lo2)>>4+((15& (lo2))=0)):(hi2)<<12+(lo2)>>4)
30 ld bc,+((hi2)>>15?~((hi2)<<12+3022-1):(hi2)<<12+3022)
31 ld bc,+(~(0xA000+(lo2)>>4+((15& (lo2))=0)))
32 ld bc,+21554
33
34 ld de,+((hi2)>>15?~((hi2)+((lo2)=0)):hi2)
35 ld de,+((hi2)>>15?~(hi2):hi2)
36 ld de,+(5-((lo2)=0))
37 ld de,+5
38
39 ld hl,+((hi2)>>15?-(lo2):lo2)
40 ld hl,+((hi2)>>15? 17184:48352)
41 ld hl,+(-(lo2))
42 ld hl,+17184
43
44
45 ;---- 0xFFFABCE1 --> 0x5431F --> 0x5431
46
47 hi3 equ 0xFFFA
48 lo3 equ 0xBCE1
49
50 ld bc,+((hi3)>>15?~((hi3)<<12+(lo3)>>4+((15& (lo3))=0)):(hi3)<<12+(lo3)>>4)
51 ld bc,+((hi3)>>15?~((hi3)<<12+3022):(hi3)<<12+3022)
52 ld bc,+(~(0xA000+(lo3)>>4+((15& (lo3))=0)))
53 ld bc,+21553
54
55 ld de,+((hi3)>>15?~((hi3)+((lo3)=0)):hi3)
56 ld de,+((hi3)>>15?~(hi3):hi3)
57 ld de,+(5-((lo3)=0))
58 ld de,+5
59
60 ld hl,+((hi3)>>15?-(lo3):lo3)
61 ld hl,+((hi3)>>15? 17183:48353)
62 ld hl,+(-(lo3))
63 ld hl,+17183
64
65 ;---- 0x54310 --> 0x5431
66
67 hi4 equ 0x5
68 lo4 equ 0x4310
69
70 ld bc,+((hi4)>>15?~((hi4)<<12+(lo4)>>4+((15& (lo4))=0)):(hi4)<<12+(lo4)>>4)
71 ld bc,+((hi4)>>15?~((hi4)<<12+1073-1):(hi4)<<12+1073)
72 ld bc,+(0x5000+(lo4)>>4)
73 ld bc,+21553
74
75 ld de,+((hi4)>>15?~((hi4)+((lo4)=0)):hi4)
76 ld de,+((hi4)>>15?~(hi4):hi4)
77 ld de,+5
78 ld de,+5
79
80 ld hl,+((hi4)>>15?-(lo4):lo4)
81 ld hl,+((hi4)>>15? 48368:17168)
82 ld hl,+lo4
83 ld hl,+17168
84
85 ;=========================================
ORG 8000
hi1 EQU FFFA
lo1 EQU BCE0
8000:013254 LD BC, 5432
8003:013254 LD BC, 5432
8006:013254 LD BC, 5432
8009:013254 LD BC, 5432
800C:110500 LD DE, 0005
800F:110500 LD DE, 0005
8012:110500 LD DE, 0005
8015:110500 LD DE, 0005
8018:212043 LD HL, 4320
801B:212043 LD HL, 4320
801E:212043 LD HL, 4320
8021:212043 LD HL, 4320
hi2 EQU FFFA
lo2 EQU BCE0
8024:013254 LD BC, 5432
8027:013254 LD BC, 5432
802A:013254 LD BC, 5432
802D:013254 LD BC, 5432
8030:110500 LD DE, 0005
8033:110500 LD DE, 0005
8036:110500 LD DE, 0005
8039:110500 LD DE, 0005
803C:212043 LD HL, 4320
803F:212043 LD HL, 4320
8042:212043 LD HL, 4320
8045:212043 LD HL, 4320
hi3 EQU FFFA
lo3 EQU BCE1
8048:013154 LD BC, 5431
804B:013154 LD BC, 5431
804E:013154 LD BC, 5431
8051:013154 LD BC, 5431
8054:110500 LD DE, 0005
8057:110500 LD DE, 0005
805A:110500 LD DE, 0005
805D:110500 LD DE, 0005
8060:211F43 LD HL, 431F
8063:211F43 LD HL, 431F
8066:211F43 LD HL, 431F
8069:211F43 LD HL, 431F
hi4 EQU 0005
lo4 EQU 4310
806C:013154 LD BC, 5431
806F:013154 LD BC, 5431
8072:013154 LD BC, 5431
8075:013154 LD BC, 5431
8078:110500 LD DE, 0005
807B:110500 LD DE, 0005
807E:110500 LD DE, 0005
8081:110500 LD DE, 0005
8084:211043 LD HL, 4310
8087:211043 LD HL, 4310
808A:211043 LD HL, 4310
808D:211043 LD HL, 4310
Emiting raw binary from 8000 to 808F
dworkin@dw-A15:~/Programovani/ZX/Forth/Automatic$
Jsou tu videt ruzne variace, vzdy 4x jakoby to same pro
;---- 0xFFFABCE0 --> 0x54320 --> 0x5432
hi1 equ 0xFFFA
lo1 equ 0xBCE0
ld bc,+__ABS20BIT_SHR_4(hi1,lo1)
ld bc,+__ABS20BIT_SHR_4(hi1,0xBCE0)
ld bc,+__ABS20BIT_SHR_4(0xFFFA,lo1)
ld bc,+__ABS20BIT_SHR_4(0xFFFA,0xBCE0)
;---- 0xFFFABCE0 --> 0x00054320
ld de,+__ABS32BIT_SHR_16(hi1,lo1)
ld de,+__ABS32BIT_SHR_16(hi1,0xBCE0)
ld de,+__ABS32BIT_SHR_16(0xFFFA,lo1)
ld de,+__ABS32BIT_SHR_16(0xFFFA,0xBCE0)
ld hl,+__ABS32BIT_AND_0xFFFF(hi1,lo1)
ld hl,+__ABS32BIT_AND_0xFFFF(hi1,0xBCE0)
ld hl,+__ABS32BIT_AND_0xFFFF(0xFFFA,lo1)
ld hl,+__ABS32BIT_AND_0xFFFF(0xFFFA,0xBCE0)
hi2 equ -6
lo2 equ -17184
atd.