Вход

Просмотр полной версии : М80 ассемблер



M80
16.02.2024, 14:58
Тут по соседству CityIceЕ рассказывает об ассемблере для Специалиста...
А работал кто с М80? Такие вот фишки у меня были в своё время. Типа, защита от пионеров.)

;-----------------------

; Вывод текстовой константы

; call: DspStr
; dbs. <string>,< > ;сообщение, > 1-го символа

; inp: PC - указатель на сообщение (D7=1 - конец)
; HL - адрес вывода в видео-буфере
; outp: PC - адрес конца сообщения+1
; HL - адрес конца вывода в видео-буфере+1
; regs: AF

DspStr: ex de,hl
ex (sp),hl ;получим адрес сообщения - сохраним DE
ex de,hl
DspMsg
ex de,hl
ex (sp),hl ;изменим адрес возврата - восстановим DE
ex de,hl
ret


Где макро DspMsg реально:
;-----------------------

; Отобразим сообщение

; inp: DE - указатель на сообщение
; (бит 7 = 1 - признак конца сообщения)
; HL - адрес вывода в видео-буфере
; outp: DE - указатель на конец сообщения + 1
; HL - адрес конца вывода в видео-буфере + 1
; regs: AF

DspMsg: ld a,(de)
inc de
xor BXlt
bit 7,a
res 7,a
ld (hl),a
inc hl
ret nz

jr DspMsg

При этом
; Без признака конца текста

DBS MACRO str
IRPC x,<str>
db '&x&' xor BXlt
ENDM
ENDM

; С признаком конца текста

DBS. MACRO str,stre
IRPC x,<str>
db '&x&' xor BXlt
ENDM
db '&stre&' or 128 xor BXlt
ENDM

; Кодирование текстовых сообщений

BXlt equ 0a5h
WXlt equ 031h ;для перекодировки адресов в таблице

Barmaley_m
22.02.2024, 23:48
Я работал с M80 довольно много. Подобных защит от пионеров, однако, не делал. Макросами пользовался, но мало. Например, такими:

GETHL MACRO ADR,OFS
LD L,(ADR+OFS)
LD H,(ADR+OFS+1)
ENDM

PUTHL MACRO ADR,OFS
LD (ADR+OFS),L
LD (ADR+OFS+1),H
ENDM

Использовал для загрузки или сохранения регистровой пары по смещению от индексных регистров, например:

GETHL IX,4
PUTHL IY, 8

Более активно пользовался макросами на PIC-8-bit процессорах:

JNZ MACRO LOC ;2/3
BTFSS STATUS,Z
GOTO LOC
ENDM

DJNZ MACRO ADR,LOC ;2/3
DECFSZ ADR,F
GOTO LOC
ENDM

Для реализации привычных "команд" условного перехода, которых у этих процессоров не было. Аналогично реализовал "команду" DJNZ.

Основная "сила" M80 для меня была не в макросах, а в наличии компоновщика и возможности собирать программу из нескольких исходных файлов. Остальные ассемблеры на Спектруме тех времен этого не могли. Там или весь проект должен был содержаться в одном исходном файле, или приходилось создавать связи между модулями вручную, с помощью EQU.

Главным недостатком M80 была его тормознутость, а также тормознутость компоновщика. Реально сожрало много времени моей жизни. Даже Паскаль (Turbo Pascal 3.0 на CP/M) быстрее компилировал.

Тормознутость M80 и компоновщика во многом обусловлена форматом объектных (.REL)-файлов. Там применяется битовый поток, поэтому для создания или считывания .REL-файла приходится выполнять много сдвиговых операций. Я даже как-то раскопал формат REL-файлов и начал делать свой объектный формат без битовых сдвигов, и компоновщик для него. Незавершенный проект.

M80
23.02.2024, 09:16
Ну на ПК то шустро работает.) Да и раньше, в CP/M всякие изгаления придумывали, типа электронного диска. А так да, флоппи елозил здорово, ходили курить пока оттранслирует.
А вообще, ассемблер достаточно серьёзный. Под 2 процессора, ну и макросредства великая вещь. Одно время хотел было перейти на другой, не под CP/M, но перепробовал 2 десятка ассемблеров и ни один не подошел. То валятся, то одного нету, то другого... Проект большой был, а перепахивать много не хотелось. Так и успокоился.)

^m00h^
23.02.2024, 13:45
Это что, Microsoft Macro 80 ? Тоесть под досом писали под спек ?

M80
23.02.2024, 14:37
Да. Только не под Специалист. Свой контроллер.

M80
25.02.2024, 20:12
Я работал с M80 довольно много. Подобных защит от пионеров, однако, не делал. Макросами пользовался, но мало.
Бармалей, ты будешь смеяться...) Всё зависит от объёмов, от надобности, от ленивости.)

; initial data:
dup cnt,dat ;dup

; Display:
.print str ;print string
prhex str,val ;message, 16-bit val in hex
prhex2 str,val1,val2 ;message, 2*16-bit val in hex
#

clrc MACRO ;;clear CF
scf
ccf
ENDM

pushr MACRO str ;;push registers
IFNB <str>
IRP src,<str>
push src
ENDM
ENDIF
ENDM

popr MACRO str ;;pop registers
IFNB <str>
IRP dst,<str>
pop dst
ENDM
ENDIF
ENDM

; output to port:
; used: A
outa MACRO dat ;;output to (c)
LOCAL rd
rd defl -0
IFB <dat>
out (c),a
ELSE
IRP rr,<a,b,c,d,e,h,l>
IFIDN <dat>,<rr>
rd defl -1
ENDIF
ENDM
IF rd
out (c),dat
ELSE ;;rd
IFIDN <dat>,<0>
xor a
ELSE
ld a,dat
ENDIF ;;IDN
out (c),a
ENDIF ;;rd
ENDIF ;;B
ENDM

; output to (b)
; used: B,A
outb MACRO dst,dat
IFNB <dst>
ld b,high dst
ENDIF
outa <dat>
ENDM

; output to (c)
; used: C,A
outc MACRO dst,dat
IFNB <dst>
ld c,low dst
ENDIF
outa <dat>
ENDM

; output to (bc)
; used: BC,A
outbc MACRO dst,dat
IFNB <dst>
ld bc,dst
ENDIF
outa <dat>
ENDM

; output to (port)
; used: A
outp MACRO port,dat
IFNB <dat>
IFIDN <dat>,<0>
xor a
ELSE
ld a,dat
ENDIF
ENDIF
out (port),a
ENDM

; input to A [moved to rr] from (port)
inp MACRO rr,port
ld a,high port
in a,(low port)
IFNB <rr>
IFDIF <rr>,<a>
ld rr,a
ENDIF
ENDIF
ENDM

; input to A [moved to rr] fm (b)
inpb MACRO rr,port
IFNB <port>
ld b,high port
ENDIF
in a,(c)
IFNB <rr>
IFDIF <rr>,<a>
ld rr,a
ENDIF
ENDIF
ENDM

; input to A [moved to rr] fm (c)
inpc MACRO rr,port
IFNB <port>
ld c,low port
ENDIF
in a,(c)
IFNB <rr>
IFDIF <rr>,<a>
ld rr,a
ENDIF
ENDIF
ENDM

; input to A [moved to rr] fm (bc)
inpbc MACRO rr,port
IFNB <port>
ld bc,port
ENDIF
in a,(c)
IFNB <rr>
IFDIF <rr>,<a>
ld rr,a
ENDIF
ENDIF
ENDM


; Префиксы для операций над
; половинками индексных регистров

; XPref
; mov c,l ;ld c,xl

xpref MACRO
db 0ddh
ENDM

ypref MACRO
db 0fdh
ENDM

; copy byte to dst from src - undoc
ld8 MACRO dst,src
IFIDN <src>,<xl> ;;ld8 r,xl
xpref
ld dst,l
ENDIF

IFIDN <src>,<xh> ;;ld8 r,xh
xpref
ld dst,h
ENDIF

IFIDN <src>,<yl> ;;ld8 r,yl
ypref
ld dst,l
ENDIF

IFIDN <src>,<yh> ;;ld8 r,yh
ypref
ld dst,h
ENDIF

IFIDN <dst>,<xl> ;;ld8 xl,r
xpref
ld l,src
ENDIF

IFIDN <dst>,<xh> ;;ld8 xh,r
xpref
ld h,src
ENDIF

IFIDN <dst>,<yl> ;;ld8 yl,r
ypref
ld l,src
ENDIF

IFIDN <dst>,<yh> ;;ld8 yh,r
ypref
ld h,src
ENDIF
ENDM

; move byte by acc
lda MACRO dst,src
IFIDN <src>,<0>
xor a
ELSE
ld a,src
ENDIF
ld dst,a
ENDM

; compare op1 with op2
cpa MACRO op1,op2
IFDIF <op1>,<a>
ld a,op1
ENDIF
cp op2
ENDM

; test on zero
tst MACRO rr
IFDIF <rr>,<a>
ld a,rr
ENDIF
or a
ENDM

; test, brunch if zero
tstz MACRO rr,adr
tst rr
jr z,adr
ENDM

; test, brunch if not zero
tstnz MACRO rr,adr
tst rr
jr nz,adr
ENDM

; while, increment
; used: AF
wi MACRO rr
local lab
ld a,rr
or a
jr z,lab

inc a
ld rr,a
lab:
ENDM

; while, decrement
; used: AF
wd MACRO rr
local lab
ld a,rr
or a
jr z,lab

dec a
ld rr,a
lab:
ENDM

; increment, brunch if not zero
ibnz MACRO rr,adr
inc rr
jr nz,adr
ENDM

; decrement, brunch if not zero
dbnz MACRO rr,adr
IFIDN <rr>,<b>
djnz adr
ELSE
dec rr
jr nz,adr
ENDIF
ENDM

;increment, brunch if zero
ibz MACRO dst,adr
inc dst
jr z,adr
ENDM

;decrement, brunch if zero
dbz MACRO dst,adr
dec dst
jr z,adr
ENDM

; increment, jump if not zero
ijnz MACRO rr,adr
inc rr
jp nz,adr
ENDM

; decrement, jump if not zero
djnz. MACRO rr,adr
dec rr
jp nz,adr
ENDM

;increment, jump if zero
ijz MACRO dst,adr
inc dst
jp z,adr
ENDM

;decrement, jump if zero
djz MACRO dst,adr
dec dst
jp z,adr
ENDM

; compare, brunch if equal
; used: AF
cbe MACRO arg1,arg2,adr
IFDIF <arg1>,<a>
ld a,arg1
ENDIF
IFIDN <arg2>,<0>
or a
ELSE
cp arg2
ENDIF
jr z,adr
ENDM

; compare, brunch if not equal
; used: AF
cbne MACRO arg1,arg2,adr
IFDIF <arg1>,<a>
ld a,arg1
ENDIF
IFIDN <arg2>,<0>
or a
ELSE
cp arg2
ENDIF
jr nz,adr
ENDM

; compare, brunch if arg1 above arg2
; used: AF
cba MACRO arg1,arg2,adr
IFDIF <arg2>,<a>
ld a,arg2
ENDIF
cp arg1
jr c,adr
ENDM

; compare, brunch if arg1 above or equal arg2
; used: AF
cbae MACRO arg1,arg2,adr
IFDIF <arg1>,<a>
ld a,arg1
ENDIF
cp arg2
jr nc,adr
ENDM

; compare, brunch if arg1 below arg2
; used: AF
cbb MACRO arg1,arg2,adr
IFDIF <arg1>,<a>
ld a,arg1
ENDIF
cp arg2
jr c,adr
ENDM

; compare, brunch if arg1 below or equal arg2
; used: AF
cbbe MACRO arg1,arg2,adr
IFDIF <arg2>,<a>
ld a,arg2
ENDIF
cp arg1
jr nc,adr
ENDM

; compare, jump if equal
; used: AF
cje MACRO arg1,arg2,adr
IFDIF <arg1>,<a>
ld a,arg1
ENDIF
IFIDN <arg2>,<0>
or a
ELSE
cp arg2
ENDIF
jp z,adr
ENDM

; compare, jump if not equal
; used: AF
cjne MACRO arg1,arg2,adr
IFDIF <arg1>,<a>
ld a,arg1
ENDIF
IFIDN <arg2>,<0>
or a
ELSE
cp arg2
ENDIF
jp nz,adr
ENDM

; compare, jump if arg1 above arg2
; used: AF
cja MACRO arg1,arg2,adr
IFDIF <arg2>,<a>
ld a,arg2
ENDIF
cp arg1
jp c,adr
ENDM

; compare, jump if arg1 above or equal arg2
; used: AF
cjae MACRO arg1,arg2,adr
IFDIF <arg1>,<a>
ld a,arg1
ENDIF
cp arg2
jp nc,adr
ENDM

; compare, jump if arg1 below arg2
; used: AF
cjb MACRO arg1,arg2,adr
IFDIF <arg1>,<a>
ld a,arg1
ENDIF
cp arg2
jp c,adr
ENDM

; compare, jump if arg1 below or equal arg2
; used: AF
cjbe MACRO arg1,arg2,adr
IFDIF <arg2>,<a>
ld a,arg2
ENDIF
cp arg1
jp nc,adr
ENDM

; compare, call if equal
; used: AF
cce MACRO arg1,arg2,adr
IFDIF <arg1>,<a>
ld a,arg1
ENDIF
IFIDN <arg2>,<0>
or a
ELSE
cp arg2
ENDIF
call z,adr
ENDM

; compare, call if not equal
; used: AF
ccne MACRO arg1,arg2,adr
IFDIF <arg1>,<a>
ld a,arg1
ENDIF
IFIDN <arg2>,<0>
or a
ELSE
cp arg2
ENDIF
call nz,adr
ENDM

; compare, call if arg1 above arg2
; used: AF
cca MACRO arg1,arg2,adr
IFDIF <arg2>,<a>
ld a,arg2
ENDIF
cp arg1
call c,adr
ENDM

; compare, call if arg1 above or equal arg2
; used: AF
ccae MACRO arg1,arg2,adr
IFDIF <arg1>,<a>
ld a,arg1
ENDIF
cp arg2
call nc,adr
ENDM

; compare, call if arg1 below arg2
; used: AF
ccb MACRO arg1,arg2,adr
IFDIF <arg1>,<a>
ld a,arg1
ENDIF
cp arg2
call c,adr
ENDM

; compare, call if arg1 below or equal arg2
; used: AF
ccbe MACRO arg1,arg2,adr
IFDIF <arg2>,<a>
ld a,arg2
ENDIF
cp arg1
call nc,adr
ENDM

; compare, return if equal
; used: AF
cre MACRO arg1,arg2,cmd
IFDIF <arg1>,<a>
ld a,arg1
ENDIF
IFIDN <arg2>,<0>
or a
ELSE
cp arg2
ENDIF
IFNB <cmd>
cmd
ENDIF
ret z
ENDM

; compare, return if not equal
; used: AF
crne MACRO arg1,arg2,cmd
IFDIF <arg1>,<a>
ld a,arg1
ENDIF
IFIDN <arg2>,<0>
or a
ELSE
cp arg2
ENDIF
IFNB <cmd>
cmd
ENDIF
ret nz
ENDM

; compare, return if arg1 above arg2
; used: AF
cra MACRO arg1,arg2
IFDIF <arg2>,<a>
ld a,arg2
ENDIF
cp arg1
ret c
ENDM

; compare, return if arg1 above or equal arg2
; used: AF
crae MACRO arg1,arg2,cmd
IFDIF <arg1>,<a>
ld a,arg1
ENDIF
cp arg2
IFNB <cmd>
cmd
ENDIF
ret nc
ENDM

; compare, return if arg1 below arg2
; used: AF
crb MACRO arg1,arg2,cmd
IFDIF <arg1>,<a>
ld a,arg1
ENDIF
cp arg2
IFNB <cmd>
cmd
ENDIF
ret c
ENDM

; compare, return if arg1 below or equal arg2
; used: AF
crbe MACRO arg1,arg2
IFDIF <arg2>,<a>
ld a,arg2
ENDIF
cp arg1
ret nc
ENDM

;-----------------------

; index-regs prefixes
XPref MACRO
db 0ddh
ENDM

YPref MACRO
db 0fdh
ENDM

; copy with 8-bit index-reg
LdX MACRO dst,src
XPref
ld dst,src
ENDM

LdY MACRO dst,src
YPref
ld dst,src
ENDM

orx MACRO ir
XPref
or ir
ENDM

ory MACRO ir
YPref
or ir
ENDM

; 16-bit load by hl
ld16 MACRO dst,rp,src
ld rp,src
ld dst,rp
ENDM

; store 16-bit val/rp to memory by ptr
; HL = HL+1
st16 MACRO ptr,rp
IFIDN <rp>,<bc>
ld (ptr),c
inc ptr
ld (ptr),b
EXITM
ENDIF
IFIDN <rp>,<de>
ld (ptr),e
inc ptr
ld (ptr),d
EXITM
ENDIF
IFIDN <rp>,<hl>
ld (ptr),l
inc ptr
ld (ptr),h
EXITM
ENDIF
IFIDN <rp>,<ix>
ldx a,l
ld (ptr),a
inc ptr
ldx a,h
ld (ptr),a
EXITM
ENDIF
IFIDN <rp>,<iy>
ldy a,l
ld (ptr),a
inc ptr
ldy a,h
ld (ptr),a
EXITM
ENDIF

ld (ptr),low rp
inc ptr
ld (ptr),high rp
ENDM

; test bc/de/hl/ix/iy
; used: AF
tst16 MACRO rp
IFIDN <rp>,<bc>
ld a,b
or c
ENDIF
IFIDN <rp>,<de>
ld a,d
or e
ENDIF
IFIDN <rp>,<hl>
ld a,h
or l
ENDIF
IFIDN <rp>,<ix>
ldx a,h
orx l
ENDIF
IFIDN <rp>,<iy>
ldy a,h
ory l
ENDIF
ENDM

; test rp, brunch if zero
tst16z MACRO rp,adr
tst16 rp
jr z,adr
ENDM

; test rp, brunch if not zero
tst16nz MACRO rp,adr
tst16 rp
jr nz,adr
ENDM

; while, increment rp
; used: AF
wi16 MACRO rp
local lab
tst16z rp,lab

inc rp
lab: ENDM


; while, decrement rp
; used: AF
wd16 MACRO rp
local lab
tst16z rp,lab

dec rp
lab: ENDM

; increment, branch if not zero
ibnz16 MACRO rp,adr
inc rp
tst16nz rp,adr
ENDM

; decrement, branch if not zero
dbnz16 MACRO rp,adr
dec rp
tst16nz rp,adr
ENDM

; increment, jump if not zero
ijnz16 MACRO rp,adr
inc rp
tst16 rp
jp nz,adr
ENDM

; decrement, jump if not zero
djnz16 MACRO rp,adr
dec rp
tst16 rp
jp nz,adr
ENDM

; Negative RP
; used: AF
neg16 MACRO rp
IFIDN <rp>,<bc>
ld a,b
cpl
ld b,a
ld a,c
cpl
ld c,a
ENDIF
IFIDN <rp>,<de>
ld a,d
cpl
ld d,a
ld a,e
cpl
ld e,a
ENDIF
IFIDN <rp>,<hl>
ld a,h
cpl
ld h,a
ld a,l
cpl
ld l,a
ENDIF
IFIDN <rp>,<ix>
ldx a,h
cpl
ldx h,a
ldx a,l
cpl
ldx l,a
ENDIF
IFIDN <rp>,<iy>
ldy a,h
cpl
ldy h,a
ldy a,l
cpl
ldy l,a
ENDIF
inc rp
ENDM

; load 16 bit rp to rp
ldbc MACRO rp
IFIDN <rp>,<bc>
ENDIF
IFIDN <rp>,<de>
ld b,d
ld c,e
ENDIF
IFIDN <rp>,<hl>
ld b,h
ld c,l
ENDIF
IFIDN <rp>,<ix>
push ix
pop bc
ENDIF
IFIDN <rp>,<iy>
push iy
pop bc
ENDIF
ENDM

ldde MACRO rp
IFIDN <rp>,<bc>
ld d,b
ld e,c
ENDIF
IFIDN <rp>,<de>
ENDIF
IFIDN <rp>,<hl>
ld d,h
ld e,l
ENDIF
IFIDN <rp>,<ix>
push ix
pop de
ENDIF
IFIDN <rp>,<iy>
push iy
pop de
ENDIF
ENDM

ldhl MACRO rp
IFIDN <rp>,<bc>
ld h,b
ld l,c
ENDIF
IFIDN <rp>,<de>
ld h,d
ld l,e
ENDIF
IFIDN <rp>,<hl>
ENDIF
IFIDN <rp>,<ix>
push ix
pop hl
ENDIF
IFIDN <rp>,<iy>
push iy
pop hl
ENDIF
ENDM

; Copy to index regs by stack
ldix MACRO rp
push rp
pop ix
ENDM

ldiy MACRO rp
push rp
pop iy
ENDM

; Add rp and acc
add16a MACRO rp
IFIDN <rp>,<bc>
add a,c
ld c,a
ld a,b
adc a,0
ld b,a
ENDIF
IFIDN <rp>,<de>
add a,e
ld e,a
ld a,d
adc a,0
ld d,a
ENDIF
IFIDN <rp>,<hl>
add a,l
ld l,a
ld a,h
adc a,0
ld h,a
ENDIF
IFIDN <rp>,<ix>
xpref
add a,l
ld l,a
xpref
ld a,h
adc a,0
xpref
ld h,a
ENDIF
IFIDN <rp>,<iy>
ypref
add a,l
ld l,a
ypref
ld a,h
adc a,0
ypref
ld h,a
ENDIF
ENDM

; add
add16 MACRO dst,rp,src
IFNB <src>
ld rp,src
ENDIF
add dst,rp
ENDM

; sbc
sbc16 MACRO dst,rp,src
IFNB <src>
ld rp,src
ENDIF
sbc dst,rp
ENDM

; move block:
move MACRO src,dst,len
IFNB <src>
ld hl,src
ENDIF
IFNB <dst>
ld de,dst
ENDIF
IFNB <len>
ld bc,len
ENDIF
ldir
ENDM

; fill block:
fill MACRO beg,len,dat
IFNB <src>
ld hl,beg
ld de,beg+1
ENDIF
IFNB <len>
ld bc,len-1
ENDIF
ld (hl),dat
ldir
ENDM

; BCD arithmetic
; dst <- dst + src
AddBCD MACRO dst,src
ld a,dst
add a,src
daa
ld dst,a
ENDM

; addition with CF
AdcBCD MACRO dst,src
ld a,dst
adc a,src
daa
ld dst,a
ENDM

; dst <- dst - src
SubBCD MACRO dst,src
ld a,dst
sub src
daa
ld dst,a
ENDM

; Subtracrion with CF
SbcBCD MACRO dst,src
ld a,dst
sbc a,src
daa
ld dst,a
ENDM

; increment packing BCD val
IncBCD MACRO reg
ld a,reg
add a,1
daa
ld reg,a
ENDM

; decrement packing BCD val
DecBCD MACRO reg
ld a,reg
sub 1
daa
ld reg,a
ENDM

;-----------------------
; Z80 undoc

inf MACRO ;;in f,(c) SF<-d7, ZF<-d6
db 0edh,70h
ENDM

outc0 MACRO ;;out (c),0
db 0edh,71h
ENDM

neg0 MACRO
db 0edh,4ch ;;44
ENDM

neg1 MACRO
db 0edh,54h
ENDM

neg2 MACRO
db 0edh,5ch
ENDM

neg3 MACRO
db 0edh,64h
ENDM

neg4 MACRO
db 0edh,6ch
ENDM

neg5 MACRO
db 0edh,74h
ENDM

neg6 MACRO
db 0edh,7ch
ENDM

im00 MACRO
db 0edh,4eh ;;46
ENDM

im01 MACRO
db 0edh,66h
ENDM

im02 MACRO
db 0edh,6eh
ENDM

im10 MACRO
db 0edh,76h ;;56
ENDM

im20 MACRO
db 0edh,7eh ;;5e
ENDM

retn0 MACRO
db 0edh,55h ;;45
ENDM

retn1 MACRO
db 0edh,5dh
ENDM

retn2 MACRO
db 0edh,65h
ENDM

retn3 MACRO
db 0edh,6dh
ENDM

retn4 MACRO
db 0edh,75h
ENDM

retn5 MACRO
db 0edh,7dh
ENDM


sli_b MACRO ;;shift left and increment
db 0cbh,30h
ENDM

sli_c MACRO
db 0cbh,31h
ENDM

sli_d MACRO
db 0cbh,32h
ENDM

sli_e MACRO
db 0cbh,33h
ENDM

sli_h MACRO
db 0cbh,34h
ENDM

sli_l MACRO
db 0cbh,35h
ENDM

sli_m MACRO
db 0cbh,36h
ENDM

sli_a MACRO
db 0cbh,37h
ENDM

; JP PE emulation
jpe MACRO addr
db 0eah
dw addr
ENDM

;-----------------------
; Пересылка с участием половинки IX

ldx MACRO dst,src
XPref
ld dst,src
ENDM

; Пересылка с участием половинки IY

ldy MACRO dst,src
YPref
ld dst,src
ENDM

; Копирование IX в DE

ix2de MACRO
ldX e,l
ldX d,h
ENDM

; Копирование DE в IX

de2ix MACRO
ldX l,e
ldX h,d
ENDM

; Копирование IY в DE

iy2de MACRO
LdY e,l
LdY d,h
ENDM

; Копирование DE в IY

de2iy MACRO
ldY l,e
ldY h,d
ENDM

;-----------------------
; dup analogue (db/ds)
dup MACRO cnt,dat
REPT cnt
IFB <dat>
db 0
ELSE
db dat
ENDIF
ENDM
ENDM

;-----------------------
; Display current switches setting

.print MACRO str
IF1
.printx str
ENDIF
ENDM

; Display 16-bit value in hex
@pr MACRO str,val
.printx str val
ENDM

prhex MACRO str,val
IF1
.radix 16
@pr <str>,%val
.radix 10
ENDIF
ENDM

; Display 2 16-bit value in hex
@pr2 MACRO str,val,val1
.printx str val val1
ENDM

prhex2 MACRO str,val,val1
IF1
.radix 16
@pr2 <str>,%val,%val1
.radix 10
ENDIF
ENDM

Sayman
26.02.2024, 06:33
ооп на М80


Title Ball ~PSW SOFT~

; This is a demo part for the Profi Vision.
; Movable visible object - Ball...

maclib maclib.inc ; Hу это пpосто макpо библиотека...
include OBJECTS.INC ; Здесь макpики и опpеделения имен
; связанных с описанием и выделением
; стандаpтных объектов.
include EVENTS.INC ; Опpеделения имен и масок событий
include VIEWS.INC ; Опpеделения флагов и полей видимых
; элементов

cmEraseAllBalls equ 1251 ; Код события-команды на котоpое pеагиpуют
; все Ball и соотв. уничтожают себя...


DeltaX equ viSkip
DeltaY equ viSkip+1
TimeXY equ viSkip+2
SpeedXY equ viSkip+3
Char equ viSkip+4

BallSkip equ viSkip+5

Object tBall, tView##, BallSkip

Constructor Ball.Init
VirtualMethods <,Ball.Draw,Ball.HandleEvent,,,,,,,,,,,,>

EndObject

M80
27.02.2024, 18:01
"Ни чё не понятно, но очень интересно."))

Barmaley_m
28.02.2024, 17:43
Ну на ПК то шустро работает.)
Это да, теперь проблем с временем компиляции нет. Но нет и проектов под Z80 - какая несправедливость :)

Да и раньше, в CP/M всякие изгаления придумывали, типа электронного диска.
У меня с ASC CP/M был RAM-DISK. Но даже на нем ассемблирование M80 и компоновка LINK исполнялись ужасно долго.

Я с двух сторон пытался решить эту проблему. Первая - пытался сделать свой компоновщик (см. выше) - хотя бы для того, чтобы ускорить сборку проекта, когда изменения внесены лишь в один небольшой исходный файл. Вторая сторона - хотел сделать турбо и процессора, и памяти. Турбо только процессора помогало мало. Много времени потратил на попытки турбировать память. Даже работало, пока микросхемы не нагреются :) Тогда, в 1995г, знаний мне не хватило, чтобы довести проект до ума.

ну и макросредства великая вещь.
Даа, меня впечатлила библиотека твоих макросов :)

Чтобы такое создать, нужно иметь обширный опыт разработки под данный процессор. Чтобы почувствовать, какие конструкции имеет смысл облечь в макросы. Чтобы, с одной стороны, не генерировать с их помощью неэффективный код; с другой стороны - чтобы объем и понятность исходного кода улучшались. И чтобы не запоминать слишком много имен и параметров этих макросов.

- - - Добавлено - - -


Это что, Microsoft Macro 80 ? Тоесть под досом писали под спек ?
Да, Microsoft Macro 80. Писали не под досом, а под CP/M.

- - - Добавлено - - -

Вот, если кто желает заняться REL-файлами - продизассемблированный LIB80 (оттуда я выяснил формат REL-файлов), и моя программа RelView2, которая считывает REL-файл и выводит его содержимое на экран в человекочитаемом виде.

По сути REL-файл представляет собой битовый поток, содержащий 8-битные кодовые литералы (им предшествует бит 0 в потоке) - они встречаются чаще всего и представляют собой результат ассемблирования, не требующий релокации. Также встречаются перемещаемые 16-битные слова - для них еще задается тип сегмента (CSEG, DSEG, COMMON). И прочие команды, задающие список символов ENTRY, EXTRN, имя модуля и т.д.

Остальные подробности легко выяснить, создав и ассемблировав пару коротких исходников и посмотрев с помощью RelView2 результаты.

M80
28.02.2024, 18:01
Даа, меня впечатлила библиотека твоих макросов :)

Чтобы такое создать, нужно иметь обширный опыт разработки под данный процессор. Чтобы почувствовать, какие конструкции имеет смысл облечь в макросы. Чтобы, с одной стороны, не генерировать с их помощью неэффективный код; с другой стороны - чтобы объем и понятность исходного кода улучшались. И чтобы не запоминать слишком много имен и параметров этих макросов.
Ну, тут на любителя.) На самом деле, важно что бы в голове не было много новых команд, с новыми параметрами... Просто я работал с другими семействами МК, с командами которых у меня сложилась ассоциация, и которые решил применить и с Z80. А так, многим это покажется лишним... Я просто показал как можно использовать макро. И считаю что это очень эффективное средство при низкоуровневом программировании.
Но это всё от бедности.) На самом деле, если есть возможность, нужно переходить на высокоуровневый язык, дабы не дублировать написание своего кода, и продуктивность своего труда была бы выше.

Barmaley_m
28.02.2024, 18:26
Но это всё от бедности.) На самом деле, если есть возможность, нужно переходить на высокоуровневый язык
Ну, что значит, бедности? В наше время любой владелец компьютера может себе позволить программировать на ЯВУ.

Только для разных средств - разные задачи. Иногда даже современные Си-компиляторы не справляются с задачей генерации эффективного кода. Или они справляются только при условии написания Си-кода определенным образом. Нужен, как минимум, контроль результатов компиляции в ассемблере для критичных участков кода; а как максимум - написание таких участков на ассемблере вручную.

Конечно, речь идет о критичных приложениях реального времени, когда быстродействия даже самых современных процессоров может не хватить. Или памяти. Или тактовую частоту нужно снизить для снижения энергопотребления. Тогда и приходится, по старинке, выжимать последние байты и такты. Это иногда нужно, и это реально помогает. Вычислительных ресурсов никогда не бывает слишком много. И навыки их экономии всегда останутся востребованы.

M80
28.02.2024, 20:08
Ну, что значит, бедности? В наше время любой владелец компьютера может себе позволить программировать на ЯВУ.

Только для разных средств - разные задачи. Иногда даже современные Си-компиляторы не справляются с задачей генерации эффективного кода. Или они справляются только при условии написания Си-кода определенным образом. Нужен, как минимум, контроль результатов компиляции в ассемблере для критичных участков кода; а как максимум - написание таких участков на ассемблере вручную.
Ну, это понятно. Сейчас да, тогда не всегда. Либо же были какие то ограничения - по скорости ли, по объёму ли... Но, я хотел сказать, что программирование на асм, зачастую пустая трата времени. Потому что его навыки не применишь к Си и его не перенесёшь в Си. Ну, перенесёшь конечно, но только чего это будет стоить.) Это не то что если бы изначально писал на Си, пусть даже применительно к какому то семейству.
Ну а сейчас, зачастую соревнования по объёму можно провести. И асм у Си не всегда выиграет.)
ПС. Да, само собой, когда нужна скорость, приходится писать на асм. Но, одно дело, это фрагменты, а не весь проект.

Barmaley_m
28.02.2024, 23:22
Не могу со всем согласиться, но участвовать в холиваре "Asm vs C" тоже не хочется. Останемся при своих.

Ты лучше посмотри по REL-файлам :) Скомпилируй мою программу RELVIEW2.MAC в эмуляторе CP/M, натрави ее на какой-нибудь REL-файл и посмотри на результаты!

M80
09.03.2024, 13:20
И что? Я давно не в теме, да и просто лень. Извини.) И меня l80 во всём устраивает.
Я тоже не сторонник холиваров, но когда смотрю на кучу своей писанины на асм, берёт тоска. Давеча, как то, х-модем захотелось на AVR перенести... Плевался почём зря.(