Nie znam asm, ale na podstawie tego co można znaleźć w kilku moich ulubionych książkach udało mi się stworzyć procedurki do rysowania i pisania na ekranie. Dumny jestem z printa, który wykorzystuje feature Actionowego “string constant”, czyli fakt, że element zerowy łańcucha napisu zawiera długość napisu, którą wydłubujemy w asm i podajemy w ICBLL, określając długość bufora.
MYGR.ACT
include "H1:ASMINC.ACT"
proc main()
int r
card savmsc=88
card textaddr=660
byte bkg=710
byte array dltb=[ 112 112 112 66 96 159 72
112 158 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8
8 8 8 8 65 78 158 ]
card dlist=560
graphics(3)
bkg=0
dlist=dltb
textaddr=40800
savmsc=40560
print("ACTION! rules")
for r=0 to 18 step 2 do
plot(0+r,0+r) drawto(0+r,10+r)
plot(0+r,10+r) drawto(10+r,10+r)
plot(10+r,10+r) drawto(10+r,0+r)
plot(10+r,0+r) drawto(0+r,0+r)
od
do od
MYLIB.ASM
org $600
graphics pha
ldx #$60
lda #close
sta iccom,x
jsr ciov
lda #open
sta iccom,x
lda <fname
sta icbal,x
lda >fname
sta icbah,x
pla
sta icaux2,x
and #$f0
eor #$10
ora #opnino
sta icaux1,x
jmp ciov
rts
; org $62b
position sty colcrs
stx colcrs+1
sta rowcrs
rts
; org $632
plot jsr position
ldx #$60
lda #putchr
sta iccom,x
lda #$0
sta icbll,x
sta icblh,x
lda color
jmp ciov
rts
; org $64b
drawto jsr position
lda color
sta atachr
ldx #$60
lda #drawln
sta iccom,x
lda #opnino
sta icaux1, x
lda #$0
sta icaux2, x
jmp ciov
rts
; org $669
print clc
sta $d4
stx $d5
ldx #0
adc #1 ;leave 0-th element
sta icbal,x
lda #putrec
sta iccom,x
lda $d5
sta icbah,x
lda #0
sta icblh,x
ldy #0
lda ($d4),y ;buflen from string
sta icbll,x ;constant's 0-th element
jsr ciov
rts
atachr equ $2fb
drawln equ $11
opnino equ $c
icaux1 equ $34a
icaux2 equ $34b
fname dta c 'S:'
colcrs equ $55
rowcrs equ $54
putchr equ $0b
icbal equ $344
icbah equ $345
iccom equ $342
icbll equ $348
icblh equ $349
color .db 1
ciov equ $e456
putrec equ $9
getrec equ $5
open equ $03
close equ $0c
Przy tego typu łączeniu kodu asm z Action! adresy procedur najbezpieczniej wziąć z listingu wygenerowanego madsem (opcja -l:ASMINC.lst).
ASMINC.ACT
proc graphics=$600(byte m)
proc position=$62B(card c, byte r)
proc plot=$632(card c, byte r)
proc drawto=$64B(card c, byte r)
proc print=$669(card msg)
Wiem że da się to zrobić lepiej ale i tak jestem z siebie dumny
Jak widać Action przekazuje parametry procedur przez akumulator i rejestry X i Y (a jeśli jest ich więcej, również przez stronę zerową). W print() adres napisu maglujemy w postaci LSB,MSB. MYLIB.ASM madsujemy i cat-ujemy MYLIB.OBX z binarką MGR.XEX.
Ciekawe jest to, że powyższy przykład w Action! po kompilacji z Runtime Action! albo uruchomieniu z cartem się wykrzacza, a działa po “zlinkowaniu” z ASMLIB.obx. Domyślam się, że chodzi o współrzędne podawane plot() i drawto(). Zapewne w przypadku procedur z carta i runtime generują one coś w stylu error 141, a procedurki w asm nie sprawdzają zakresu współrzędnych i jadą dalej poza pamięcią obrazu… Na chwilę obecną nie jestem w stanie tego lepiej wytłumaczyć. Ważne że działa.
Konwertować do bloków kodu [] mi się tego póki co nie chce, ale pewnie niebawem i to przetrenuje.
Kolejny, ważniejszy krok, to stworzenie procedur piszących bezpośrednio do pamięci ekranu danego trybu graficznego. JHusak kiedyś wspominał o szybkim plot(), jest nawet o tym wzmianka w FAQ o Action! atarionline.pl, ale od jakiegoś czasu ten link się zapętla.