[SDK] Новая математика для кросс-компилятора в 8080/z80
Moderator: Shaos
- 
				Shaos  
- Admin
- Posts: 24402
- Joined: 08 Jan 2003 23:22
- Location: Silicon Valley
[SDK] Новая математика для кросс-компилятора в 8080/z80
Я завожу эту новую тему в связи с тем, что мне надо заменить математику в nedoPC SDK с вынутой из Small-C 1984 года на свою (чтобы 100% библиотек SDK объявить PUBLIC DOMAIN). Планируется написать новые подпрограммы в мнемониках i8080 и z80, чтобы подменить содержимое теперешнего _CLIB.A - большинство кода будет вставляться в генерируемый ассемблер как есть (т.е. как макросы - без вызова подпрограмм), а всё ещё вызываемыми по CALL подпрограммами по-видимому останутся DIVMOD, MULT и наверное сдвиги...
			
			
									
						
										
						- 
				Shaos  
- Admin
- Posts: 24402
- Joined: 08 Jan 2003 23:22
- Location: Silicon Valley
Re: [SDK] Новая математика для кросс-компилятора
Подсмотрел тут у Алоне как он делает NEG HL в NedoLang:
Интересно, а можно компактнее и/или быстрее? типа
Выходит больше и дольше  Тоже...
Тоже...  
			
			
									
						
										
						Code: Select all
  XOR A ; +4=4
  SUB L ; +4=8
  LD L,A ; +4=12
  SBC H ; +4=16
  SUB L ; +4=20
  LD H,A ; +4=24
Code: Select all
  LD DE,0 ; +10=10
  EX DE,HL ; +4=14
  OR A ; +4=18
  SBC HL,DE ; +15=33
 
Code: Select all
  LD A,H ; +4=4
  CPL ; +4=8
  LD H,A ; +4=12
  LD A,L ; +4=16
  CPL ; +4=20
  LD L,A ; +4=24
  INC HL ; +6=30

- 
				Shaos  
- Admin
- Posts: 24402
- Joined: 08 Jan 2003 23:22
- Location: Silicon Valley
Re: [SDK] Новая математика для кросс-компилятора в 8080/z80
Первые ласточки - логические AND и OR (в мнемониках RASM i8080):
(они и до этого были мои самописные, но в виде подпрограмм, а теперь будут в виде макросов)
			
			
									
						
										
						Code: Select all
// 0x80 // &&  A,B -> A&&B
*EXPR 0x80
#genlab %l1
        POP_D
        MOV_A,D
        ORA_E
        JZ      %l1
        MOV_A,H
        ORA_L
        JZ      %l1
        MVI_A,  #FF
%l1
        MOV_H,A
        MOV_L,A
*
// 0x81 // ||  A,B -> A||B
*EXPR 0x81
#genlab %l1
#genlab %l2
        POP_D
        MOV_A,D
        ORA_E
        JNZ     %l1
        MOV_A,H
        ORA_L
        JZ      %l2
%l1
        MVI_A,  #FF
%l2
        MOV_H,A
        MOV_L,A
*
- 
				Shaos  
- Admin
- Posts: 24402
- Joined: 08 Jan 2003 23:22
- Location: Silicon Valley
Re: [SDK] Новая математика для кросс-компилятора в 8080/z80
Идём дальше:
P.S. 24 июля 2024 года исправил косяк в != заменив второй CMP на SUB, чтобы в регистре A пролучился 0 если байты были равны...
			
			
									
						
										
						Code: Select all
// 0x90 // ==  A,B -> A==B
*EXPR 0x90
#genlab %l1
#genlab %l2
        POP_D
        MOV_A,H
        CMP_D
        JNZ     %l1
        MOV_A,L
        CMP_E
        JNZ     %l1
        LXI_H,  #FFFF
        JMP     %l2
%l1
        LXI_H,  0
%l2
*
// 0x91 // !=  A,B -> A!=B
*EXPR 0x91
#genlab %l1
#genlab %l2
        POP_D
        MOV_A,H
        CMP_D
        JNZ     %l1
        MOV_A,L
        SUB_E
        JZ      %l2
%l1
        MVI_A,  #FF
%l2
        MOV_H,A
        MOV_L,A
*
- 
				Mondx
- Doomed
- Posts: 573
- Joined: 10 Aug 2022 07:27
- Location: Crimea
Re: [SDK] Новая математика для кросс-компилятора в 8080/z80
Пользуйся Microsoft, а то какую то % пишешь. Ей богу.
			
			
									
						
										
						- 
				Shaos  
- Admin
- Posts: 24402
- Joined: 08 Jan 2003 23:22
- Location: Silicon Valley
Re: [SDK] Новая математика для кросс-компилятора в 8080/z80
Зачем мне пользоваться Microsoft? У них есть компилируемый язык высокого уровня для 8080?Mondx wrote:Пользуйся Microsoft, а то какую то % пишешь. Ей богу.

Или у них есть матлиба под 8080 с сомнительной лицензией и ограничениями в использовании?
Я же написал выше - мне PUBLIC DOMAIN нужен...
- 
				Shaos  
- Admin
- Posts: 24402
- Joined: 08 Jan 2003 23:22
- Location: Silicon Valley
Re: [SDK] Новая математика для кросс-компилятора в 8080/z80
Итак, идём дальше:
Для проверки разнообразных условий я написал вот такой тест на Robby:
Этот тест компилируется в бинарник 5K с хвостиком, который успешно выполняется в эмуляторе Pseudo-86RK:
			
			
						Code: Select all
// 0x92 // >   A,B -> A>B
*EXPR 0x92
#genlab %l1
#genlab %l2
        POP_D
        MOV_A,E
        SUB_L
        MOV_L,A
        MOV_A,D
        SBB_H
        MOV_H,A
        ORA_L
        JZ      %l2
        MOV_A,H
        ANA_A
        JM      %l1
        LXI_H,  #FFFF
        JMP     %l2
%l1
        LXI_H,  0
%l2
*
// 0x93 // <   A,B -> A<B
*EXPR 0x93
#genlab %l1
#genlab %l2
        POP_D
        MOV_A,L
        SUB_E
        MOV_L,A
        MOV_A,H
        SBB_D
        MOV_H,A
        ORA_L
        JZ      %l2
        MOV_A,H
        ANA_A
        JM      %l1
        LXI_H,  #FFFF
        JMP     %l2
%l1
        LXI_H,  0
%l2
*
// 0x94 // >=  A,B -> A>=B
*EXPR 0x94
#genlab %l1
#genlab %l2
#genlab %l3
        POP_D
        MOV_A,L
        SUB_E
        MOV_L,A
        MOV_A,H
        SBB_D
        MOV_H,A
        ORA_L
        JZ      %l1
        MOV_A,H
        ANA_A
        JP      %l2
%l1
        LXI_H,  #FFFF
        JMP     %l3
%l2
        LXI_H,  0
%l3
*
// 0x95 // <=  A,B -> A<=B
*EXPR 0x95
#genlab %l1
#genlab %l2
#genlab %l3
        POP_D
        MOV_A,E
        SUB_L
        MOV_L,A
        MOV_A,D
        SBB_H
        MOV_H,A
        ORA_L
        JZ      %l1
        MOV_A,H
        ANA_A
        JP      %l2
%l1
        LXI_H,  #FFFF
        JMP     %l3
%l2
        LXI_H,  0
%l3
*
Code: Select all
// CREATED: 20-JUL-2024
ROBOT "TEST-0002"
AUTHOR "SHAOS"
+INC/ROBBY
main()
{
 text "<><><><><><><><><><> MAIN-BEGIN"
 def arr[10] = {-1, 0, 1, 0}
 EQ1 = arr[1] == arr[2]
 NE1 = arr[1] != arr[2]
 GT1 = arr[1] >  arr[2]
 GE1 = arr[1] >= arr[2]
 LT1 = arr[1] <  arr[2]
 LE1 = arr[1] <= arr[2]
 EQ2 = arr[1] == arr[0]
 NE2 = arr[1] != arr[0]
 GT2 = arr[1] >  arr[0]
 GE2 = arr[1] >= arr[0]
 LT2 = arr[1] <  arr[0]
 LE2 = arr[1] <= arr[0]
 EQ3 = arr[1] == arr[3]
 NE3 = arr[1] != arr[3]
 GT3 = arr[1] >  arr[3]
 GE3 = arr[1] >= arr[3]
 LT3 = arr[1] <  arr[3]
 LE3 = arr[1] <= arr[3]
 termsetsay(0,5,2)
 say "F?#&EQ1 T?#&NE1 F?#>1 F?#&GE1 T?#<1 T?#&LE1 "
 termsetsay(0,6,2)
 say "F?#&EQ2 T?#&NE2 T?#>2 T?#&GE2 F?#<2 F?#&LE2 "
 termsetsay(0,7,2)
 say "T?#&EQ3 F?#&NE3 F?#>3 T?#&GE3 F?#<3 T?#&LE3 "
 SUM = 0
 if(!EQ1&&NE1) SUM=SUM+1
 if(!GT1)      SUM=SUM+2
 if(!GE1)      SUM=SUM+4
 if(LT1)       SUM=SUM+8
 if(LE1)       SUM=SUM+16
 if(!EQ2&&NE2) SUM=SUM+32
 if(GT2)       SUM=SUM+64
 if(GE2)       SUM=SUM+128
 if(!LT2)      SUM=SUM+256
 if(!LE2)      SUM=SUM+512
 if(EQ3&&!NE3) SUM=SUM+1024
 if(!GT3)      SUM=SUM+2048
 if(GE3)       SUM=SUM+4096
 if(!LT3)      SUM=SUM+8192
 if(LE3)       SUM=SUM+16384
 termsetsay(0,10,2)
 if(SUM==#7FFF) say "GOOD #&SUM "
 else say "BAD #&SUM "
 text "<><><><><><><><><><> MAIN-END"
}
+LIB/P2TERM
You do not have the required permissions to view the files attached to this post.
			
						
										
						- 
				Shaos  
- Admin
- Posts: 24402
- Joined: 08 Jan 2003 23:22
- Location: Silicon Valley
Re: [SDK] Новая математика для кросс-компилятора в 8080/z80
Code: Select all
// 0xA0 // +   A,B -> A+B
*EXPR 0xA0
        POP_D
        DAD_D
*
// 0xA1 // -   A,B -> A-B
*EXPR 0xA1
        POP_D
        MOV_A,E
        SUB_L
        MOV_L,A
        MOV_A,D
        SBB_H
        MOV_H,A
*
...
// 0xC0 // &   A,B -> A&B
*EXPR 0xC0
        POP_D
        MOV_A,D
        ANA_H
        MOV_H,A
        MOV_A,E
        ANA_L
        MOV_L,A
*
// 0xC1 // |   A,B -> A|B
*EXPR 0xC1
        POP_D
        MOV_A,D
        ORA_H
        MOV_H,A
        MOV_A,E
        ORA_L
        MOV_L,A
*
// 0xC2 // ^   A,B -> A^B
*EXPR 0xC2
        POP_D
        MOV_A,D
        XRA_H
        MOV_H,A
        MOV_A,E
        XRA_L
        MOV_L,A
*
...
// 0xE0 // -   A -> -A
*EXPR 0xE0
        MOV_A,H
        CMA
        MOV_H,A
        MOV_A,L
        CMA
        MOV_L,A
        INX_H
*
// 0xE1 // ~   A -> ~A
*EXPR 0xE1
        MOV_A,H
        CMA
        MOV_H,A
        MOV_A,L
        CMA
        MOV_L,A
*
// 0xE2 // !   A -> !A
*EXPR 0xE2
#genlab %l1
        MOV_A,H
        ORA_L
        JZ      %l1
        LXI_H,  1
%l1
        DCX_H
*
// 0xF0 // ?:         A,B,C -> A?B:C
*EXPR 0xF0
#genlab %l1
        POP_D
        POP_B
        MOV_A,B
        ORA_C
        JZ      %l1
        XCHG
%l1
*
- 
				shiny  
- Maniac
- Posts: 324
- Joined: 14 Oct 2023 06:59
Re: [SDK] Новая математика для кросс-компилятора в 8080/z80
HL=-HL
			
			
									
						
										
						Code: Select all
xor a
sub l
ld l,a
sbc a,a
sub h
ld h,a
- 
				Shaos  
- Admin
- Posts: 24402
- Joined: 08 Jan 2003 23:22
- Location: Silicon Valley
Re: [SDK] Новая математика для кросс-компилятора в 8080/z80
см. второй пост с начала - Алоне похожим образом делал
тут правда хитрее, хоть и такое же количество тактов и байтов
откуда дровишки?
			
			
									
						
										
						тут правда хитрее, хоть и такое же количество тактов и байтов
откуда дровишки?

- 
				shiny  
- Maniac
- Posts: 324
- Joined: 14 Oct 2023 06:59
Re: [SDK] Новая математика для кросс-компилятора в 8080/z80
часть кода z80 можно найти на ресурсах, посвященных с Texas Instruments.
			
			
									
						
										
						- 
				Shaos  
- Admin
- Posts: 24402
- Joined: 08 Jan 2003 23:22
- Location: Silicon Valley
Re: [SDK] Новая математика для кросс-компилятора в 8080/z80
Тут ещё такой момент - надо ли детектировать особые случаи при сдвигах? Типа если сдвиг 8 бит, то зачем бежать крутить биты если можно просто байт переставить? Другой момент, что на проверку и переход тоже время тратится, но оно всё таки будет меньше чем двигать побитно. Тоже самое с умножением - зачем двигать биты если один из множителей 0 или скажем 1? Ведь результат будет заведомо известен...
P.S. Сдвиги можно наверное как-то вот так сделать:Тут детектируется 2 особых случая - сдвиг на 0 ( см. RZ ) и сдвиг на 8 ( см. CPI 8 ). Кроме того сдвиг берётся по маске 31 - это чтобы сымитировать сишное поведение, когда сдвиг на 32 это тоже самое, что сдвиг на 0 (даже в случае 16-битных целых) - заодно устанавливаются флаги, чтобы быстро выскочить, если это был сдвиг на 0 (в этот момент в HL уже будет сидеть то, что при входе было в DE).
			
			
									
						
										
						P.S. Сдвиги можно наверное как-то вот так сделать:
Code: Select all
\ SHIFT DE LEFT BY L&31 AND RETURN IN HL
SHIFTL: XCHG
        MOV_A,E
        ANI     31
        RZ      \ RETURN IF SHIFT BY 0
        CPI     8
        JNZ     SHIFTL1
        \ SPECIAL CASE - SHIFT BY 8
        MOV_H,L
        MVI_L,  0
        RET
SHIFTL1:
        DAD_H
        DCR_A
        JNZ     SHIFTL1
        RET
\ SHIFT DE RIGHT (ARITHMETICALLY) BY L&31 AND RETURN IN HL
SHIFTR: XCHG
        MOV_A,E
        ANI     31
        RZ      \ RETURN IF SHIFT BY 0
        MOV_D,A
        CPI     8
        JZ      SHIFTR3
        MOV_A,H
        RAL
        JC      SHIFTR2
SHIFTR0:
        XRA_A
        MOV_A,H
        RAR
        MOV_H,A
        MOV_A,L
        RAR
        MOV_L,A
        DCR_D
        JNZ     SHIFTR0
        RET
SHIFTR1:
        STC
SHIFTR2:
        MOV_A,H
        RAR
        MOV_H,A
        MOV_A,L
        RAR
        MOV_L,A
        DCR_D
        JNZ     SHIFTR1
        RET
SHIFTR3:
        \ SPECIAL CASE - SHIFT BY 8
        MOV_L,H
        MOV_A,H
        RAL
        JC      SHIFTR4
        MVI_H,  0
        RET
SHIFTR4:
        MVI_H,  #FF
        RET
- 
				shiny  
- Maniac
- Posts: 324
- Joined: 14 Oct 2023 06:59
Re: [SDK] Новая математика для кросс-компилятора в 8080/z80
Идея интересная, но оптимизация заведет до абсурда - при сдвигах, кое количество кратно 8.
			
			
									
						
										
						- 
				Shaos  
- Admin
- Posts: 24402
- Joined: 08 Jan 2003 23:22
- Location: Silicon Valley
Re: [SDK] Новая математика для кросс-компилятора в 8080/z80
У меня 16-битные целые поэтому только сдвиг на 8 является часто встречающимся случаем, а сдвиг на 16 уже всё уведёт за пределы и я не думаю, что этот вариант надо ускорять...
			
			
									
						
										
						- 
				shiny  
- Maniac
- Posts: 324
- Joined: 14 Oct 2023 06:59
Re: [SDK] Новая математика для кросс-компилятора в 8080/z80
А не может такого быть, что используется var>>bitcount или явно var>>8 ?
			
			
									
						
										
						 
				