;**************************************************************
; BASICODE v1.0
; Bir basic satırının dibine makine kodu ekleme ve
; kodu normal bir basic programı gibi save etme rutini.
; Basicode'un başlangıç adresi, basicode haline getirilecek
; çalışan kodun kendi adresinden $73 eksik olmalıdır.
; Örnek program $8000 adresinden itibaren bulunmaktadır ve
; çalışma adresi $8000'dir.
;**************************************************************
org $8000-$73
;==============================================================
run_adr equ $8000
kaynak equ prog_str
hedef equ prog_str
uzunluk equ prog_end-prog_str
prg_uzunluk equ uzunluk + (prog_str-basic_line) ; 30
; 30= Basic satırı + relocator uzunluğu
;==============================================================
; PROGRAM SAVE BÖLÜMÜ
; START TAPE... MESAJINI YAZDIR VE TUŞA BASILMASINI BEKLE
;--------------------------------------------------------------
basicode ld a,$fd ; Ensure that channel 'K' is open.
call $1601
xor a ; Signal 'first message'.
ld de,$09a1 ;'Start tape, then press any key.'
call $0c0a
set 5,(iy+$02) ;Signal 'screen will require to be cleared'
scf
call $15d4 ;Bir tuşa basılmasını bekle
;--------------------------------------------------------------
; Basic satırını + relocatoru ve asıl programı
; basic satırının dibine kopyala
;--------------------------------------------------------------
ld hl,basic_line
ld de,23755
ld bc,30
ldir
ld hl,kaynak
ld de,$5ce9
ld bc,uzunluk
ldir
;--------------------------------------------------------------
; Header'i ve Basic + Code haline getirilen programı kaydet
;--------------------------------------------------------------
xor a
ld ix,header
ld de,17
call $04c2
ld a,$ff
ld ix,23755
ld de,prg_uzunluk
scf
call $04c2
rst 8
defb 255 ; Hata kodu-1
;==============================================================
; FILE HEADER BİLGİSİ
;==============================================================
header:
file_type defb 0 ; dosya tipi: program
file_name defb $16,1,0 ; AT 1,0
defb $af,$3a ; CODE
defm "HADES"
data_lenght defw prg_uzunluk
start_line defw 6151
prog_lenght defw prg_uzunluk
;==============================================================
; 6151 RANDOMIZE USR 23755 satırının dataları (16 byte)
; relocator rutini (14 byte) --- Toplam 30 byte
;--------------------------------------------------------------
basic_line defb $18,$07,$08,$00,$f9,$c0,$32,$33
defb $37,$35,$35,$0e,$00,$00,$cb,$5c
;--------------------------------------------------------------
relocator ld hl,$5ce9 ; programın bulunduğu adres
ld de,hedef ; programın asıl adresi
ld bc,uzunluk ; programın uzunluğu
ldir
jp run_adr ; programın çalışma adresi
;==============================================================
; BASIC + CODE haline getirilecek kod burada olmalıdır.
;==============================================================
prog_str:
incbin "dikey_simetrik_ekran.bin"
prog_end:
;--------------------------------------------------------------
end basicode
;==============================================================
Başka bir başlıkta yer alan basic satırının dibine kod ekleme konusu için yeni başlık açmaya karar verdim.
Spectrumda hafızada bulunan bir makina dili program/data SAVE "programadı" CODE adres,uzunluk şeklinde kaydedilir. LOAD "" CODE ile yüklenir.
LOAD "" CODE adres komutu kullanılırsa kod farklı bir adrese yüklenebilir.
Basic programları kayıt edilirken programın auto-start olması için SAVE "programadı" LINE satır_no şeklinde komut kullanılır. satır_no basic programın hangi satırdan itibaren çalışacağını belirtir.
Ancak LOAD "" CODE komutu için autostart özelliği yoktur. Bu yüzden içinde, CLEAR adres-1, LOAD "" CODE ve kodu çalıştırmak için RANDOMIZE USR adres gibi komutlar bulunan bir basic program yazılır ve auto-start yapacak şekilde kayıt edilir. Sonrasında ise kod kaydedilir. Dolayısıyla kod yüklemek için bir basic programa ihtiyaç duyulur.
İster basic program isterse kod olsun save işlemi sırasında önce bir header bilgisi kaydedilir hemen arkasına basic program veya kod kaydedilir.
Kısaca, bir kod kaydetmek ve yükleyip çalıştırmak için,
Header + Basic Loader + Header + kod/data şeklinde bir kayıt süreci vardır.
Gelelim BASICODE programına;
BASICODE hafızada bulunan bir makina dili programını bir Basic programıymış gibi sadece Header + Kod/data şekline getirir ve save eder.
Basicode'un uzunluğu 115 ($73) bayttır. Daha önce yazıp çalıştırdığınız bir programınızın listesinin başına Basicode'u eklemeniz ve programın başlangıç adresini değiştirip yeniden compile etmeniz yeterlidir. Ayrıca kendi kodunuzun çalışma adresini listenin başındaki run_adr kısmına girmeniz gerekmektedir. Veya daha önceden binary file olarak save edilen bir programı ekleyebilirsiniz.
Örnek programda, normalde $8000 adresinde bulunan ve aynı adresten itibaren çalışan bir binary file kullanılmıştır. Programın başlangıç adresi $8000-$73 olarak tanımlanmıştır.
Şimdi gelelim basicode'un bir özelliğine.
Normalde auto-start bir programın listesini yükleme sonrası göremezsiniz. Fakat yükleme işlemini LOAD "" ile değilde MERGE "" ile yaparsanız program auto-start olsa bile çalışmaz ve programın listesini görebilirsiniz.
BASICODE ile oluşturulan program LOAD "" yüklenip çalışmasına rağmen MERGE "" ile yüklendiğinde makina resetlenmektedir.
Program listesinde, basic_line satırındaki $08 ve $00 değerleri normalde satır uzunluğunun LO-HI formatındaki değerleridir ama olması gereken değerlerden farklı girilmiştir.
$08-$00 yerine $00-$FF girilirse MERGE "" komutu ile yükleme sonrası Out Of Memory hatası alınır ve liste alınamaz.
$08-$00 yerine $09-$00 girilirse MERGE "" komutu ile yükleme sonrası ekran kayar ve spectrum kilitlenir.
$08-$00 yerine $07-$00 girilirse MERGE "" komutu ile yükleme sonrası liste gözükür ama editlenemez.
Basicode'u printer buffer'da çalışacak şekilde yazmaya çalıştım ama beceremedim. +2 modelde basicode'u printer buffera attığımda makina sapıttı. 48K modelde önce printer buffera basicode'u yükleyip sonra asıl kodu yüklediğimde printer bufferın temizlendiğini gördüm.
Daha sonra bir basic programı yazıp yükleme ve çalıştırma adreslerini gerekli yerlere poke etmeyi düşündüm. Önce .tap dosyasını manuel olarak insert edip basic üzerinden input komutuyla basicode haline getirilecek programın ismini girip load name$ code gibi birşey olur mu diye tırmaladım. Diğer yandan program uzunluğunu ve çalışma adreslerinide elle girmek gerekecekti. Yükleme sonrası sistem değişkenleri kullanarak program uzunluğu bulunabilir diye düşündüm. Düşündüm, taşındım sonunda basic bilgimin buna yetmediğini anladım. Basic'i en son 1987'de sınavda kullanmıştım.
Aşağıdaki gibi bir program tasarlamıştım
10 load "basicode" code 23296
20 input "program adı:" pn$
30 load pn$ code
40 input "program uzunluğu:" pu : poke ...,.. : poke ...,..
50 input "çalışma adresi:" ça : poke ...,.. : poke ...,..
60 randomize usr 23296