halaman 2 b
Proses: :
CMP AX,1 ; Apakah error kode 1 ?
JNE Err2 ; Bukan! lompat ke Err2
Cetak Error1 ; Ya! Cetak pesan dari kode error 1
JMP Exit ; Keluar
Err2:
CMP AX,2 ; Apakah error kode 2 ?
JNE Err3 ; Bukan! lompat ke Err3
Cetak Error2 ; Ya! Cetak pesan dari kode error 2
JMP Exit ; Keluar
Err3:
CMP AX,3 ; Apakah error kode 3 ?
JNE Err4 ; Bukan! lompat ke Err4
Cetak Error3 ; Ya! Cetak pesan dari kode error 3
JMP Exit ; Keluar
Err4:
:
:
Apakah cara diatas sudah tepat ? Tidak!. Bila pengecekan dari kode
kesalahan hanyalah 1 atau 2 buah, cara diatas dapat kita pakai . Bagaimana
bila kode kesalahan yang akan pelajar cek, ternyata jumlahnya mencapai ratusan?
program kita akan tampak bertele-tele dan panjang selain itu ukuran file akan
menjadi sangat besar.
Salah satu cara yang dapat kita pakai untuk memecahkan masalah diatas
yaitu dengan membuat suatu tabel array yang berisi alamat offset dari masingmasing pesan kesalahan. lalu dari tabel alamat kode kesalahan ini
dipakai untuk mencetak pesan salah yang dihasilkan.
Cetak MACRO Kal
MOV AH,09
MOV DX,Kal
INT 21h
ENDM
;/====================/;
.MODEL SMALL
.CODE
ORG 100h
TData : JMP Proses
Error01 DB 'Salah perintah $'
Error02 DB 'File tidak ditemukan $'
Error03 DB 'Path tidak ditemukan $'
Error04 DB 'File yang dibuka terlalu banyak $'
Error05 DB 'Operasi ditolak $'
Error06 DB 'pemakaian file handle yang salah $'
Error07 DB 'MCB(Memory Control Blocks) sudah rusak $'
Error08 DB 'Kekurangan memory $'
Error09 DB 'Alamat memory blok salah $'
Error10 DB 'Environment String salah $'
Error11 DB 'Kesalahan format $'
Error12 DB 'Kode akses salah $'
Tabel DW Error01,Error02,Error03,Error04,Error05
DW Error06,Error07,Error08,Error09,Error10
DW Error11,Error12
Test_Error DW 03
Proses :
MOV AX,Test_Error
DEC AX
ADD AX,AX
MOV BX,AX
CETAK Tabel[BX] ; Cetak pesan kode error
INT 20h
END TData
program 23.4. Cara yang praktis untuk mencetak arti kode kesalahan DOS
Bila program 23.4. dijalankan, maka pada layar akan tercetak:
Path tidak ditemukan
Seperti yang diharapkan, arti kode error 03(Test_Error) akan tercetak
pada layar. kita bisa mengubah kode salah pada variabel Test_Error dengan
angka 01 sampai 12 untuk melihat pesan yang akan ditampilkan.
lihat :
Pada varibel Tabel pelajar mencatat alamat offet dari masing- masing pesan
kesalahan dengan cara:
Tabel DW Error01,Error02,Error03,Error04,Error05
DW Error06,Error07,Error08,Error09,Error10
DW Error11,Error12
yang mana masing-masing alamat offset memakai 1 word.
MOV AX,Test_Error
DEC AX
sebab kode error yang pertama yaitu 01, maka perlu pelajar kurangi dengan
1 agar menjadi 0. sehingga kode error 1 akan menunjuk pada word
pertama pada Tabel yang pelajar ketahui bahwa word pertama dari Tabel yaitu
alamat offset pesan kode salah 01.
ADD AX,AX
MOV BX,AX
sebab setiap alamat offset dari pesan kode salah memakai 1 word
atau 2 byte, maka untuk mengambil word selanjutnya dari Tabel yang mencatat
alamat offset pesan kode error selanjutnya, pelajar harus mengalikan kode error
dengan 2 atau menambah kode error dengan dirinya sendiri.
CETAK Tabel[BX]
lalu dengan Register Indirect Addressing pelajar mengambil alamat
offset pesan kode salah dari Tabel. Seperti biasa, pada pencetakan kalimat
pelajar mengambil alamat offset dari suatu string yang diakhiri dengan tanda '$'
untuk dicetak dengan fungsi 09 dari Dos. Pada pencetakan string ini alamat
offset sudah diperoleh dari Tabel[BX], sehingga perintah: "LEA DX,Kal" dari
fungsi 09 dapat dirubah menjadi: "MOV DX,Kal"
program RESIDEN
sudah dibahas mengenai pengertian dasar interupsi, bila kita
sudah lupa, bacalah kembali sebelum membaca bagian ini. Pada bagian ini akan
pelajar lihat lebih lanjut khusus mengenai vektor interupsi.
Seperti yang sudah dikatakan, setiap interupsi memakai 4 byte memory
sebagai alamat awal interupsi, yaitu alamat yang akan dituju setiap terjadi
interupsi. Keempat byte ini dicatat pada Interrupt Vektor Table yang ada
pada memory rendah, 0000:0000 sampai 0000:03FFh. sehingga , interupsi 00
memakai alamat 0000:0000-0000:0003, interupsi 01 memakai
alamat 0000:0004-0000:0007, dan seterusnya. Untuk mencari alamat awal dari
suatu nomor interupsi dipakai rumus:
Alamat Awal = 4 * Nomor-Interupsi
contoh : , setiap kali pelajar menekan tombol PrtScr untuk
mencetak isi layar pada printer akan selalu terjadi interupsi 05. Komputer
lalu akan menuju alamat awal interupsi 05, yaitu 0000:0020 (4*05=20). Dari
alamat awal ini lalu akan dilihat isi dari keempat byte, yaitu pada alamat
0000:0020 - 0000:0023. Keempat byte ini mencatat alamat CS(2 byte) dan IP(2
byte), yaitu alamat yang akan dituju oleh komputer selanjutnya. contoh isi
dari keempat byte ini yaitu 3200h:0D8Bh, artinya komputer akan melompat pada
alamat itu dan menjalankan program yang ada pada alamat itu
sampai bertemu dengan perintah IRET. program inilah yang dinamakan sebagai
Interrupt Handler 05, yaitu program yang akan dilakukan setiap kali terjadi
interupsi 05. Secara default program yang akan dilakukan ada pada
BIOS, yang mana program itu akan mencetak tampilan pada layar ke printer.
Untuk melihat isi dari alamat awal suatu vektor interupsi dapat
dipakai dua cara. Cara pertama, yaitu dengan membaca secara langsung
keempat byte alamat awal yang mencatat alamat berturut-turut Offset Lo, Offset
Hi, Segment Lo dan Segment Hi dari interrupt handler. Cara kedua yaitu dengan
memakai interupsi 21h fungsi 35h. Cara kedua lebih mudah untuk dipakai ,
oleh sebab itu akan pelajar pakai pada program -program selanjutnya.
Untuk memakai fungsi ke 35h ini, isilah AH dengan 35h dan AL dengan
nomor vektor interupsi sebelum dilakukan interupsi 21h. Hasil dari
interupsi ini akan disimpan pada pasangan register ES:BX. yang mana ES mencatat
alamat segment dan BX mencatat alamat offset vektor interupsi dari nomor
interupsi yang dimasukkan pada AL.
Ambil_Vec MACRO NoInt,Alamat
MOV AH,35h ; Servis untuk mencari vektor
MOV AL,NoInt ; No inteurpsi
INT 21h ; lakukan
MOV Alamat,BX ; Offset
MOV Alamat[2],ES ; Segment
ENDM
Untuk memakai macro ini kita bisa menyediakan suatu varibael 2 word
untuk menampung alamat hasil dari interupsi ini, seperti: Alamat DW ?,?.
Secara default, nomor interupsi 00h-7Fh akan menjalankan program yang
ada ROM BIOS, dan nomor interupsi 20h-FFh akan menjalankan program yang
disediakan oleh DOS. Interrupt Handler yang disediakan oleh BIOS ini tidak
bisa dihapus secara perangkat lunak dan selalu tersedia pada setiap komputer.
sedang Interrupt Handler yang disediakan oleh DOS akan tersedia pada saat
sistem operasi DOS sudah masuk kedalam memory komputer.
Suatu interrupt handler bisa saja diganti, contoh pelajar menginginkan
penekanan tombol PrtScr tidak mencetak isi layar namun mem-BOOT komputer sama
halnya dengan penekanan tombol Ctrl+Alt+Del. sebab Interrupt handler yang
asli, baik dari BIOS atau DOS tidak bisa dihapus maka cara yang dipakai
untuk merubah interrupt handler yaitu dengan mengganti isi dari Interrupt
Vektor Table.
Untuk mengganti atau mengarahkan suatu nomor interupsi dapat secara
langsung atau memakai fungsi 25h dari interupsi 21h. Untuk memakai
fungsi ini, isilah AH dengan 25h, AL dengan nomor interupsi yang akan diganti
vektornya, pasangan DS:DX berisi alamat yang akan dituju pada saat terjadi
interupsi itu .
Arah_Vec MACRO NoInt,Alamat
MOV AX,Alamat[2]
MOV DS,AX ; DS = segment
MOV DX,Alamat ; DX = offset
MOV AH,25h ; Servis untuk merubah vektor
MOV AL,NoInt ; No interupsi
INT 21h
ENDM
Sama seperti macro untuk memperoleh alamat vektor interupsi, untuk
memakai macro ini kita harus menyediakan suatu varibael 2 word yang
dipakai sebagai penampung alamat yang akan dituju dari suatu interupsi,
seperti: Alamat DW ?,?.
Pada program berikut ini akan kita lihat bagaimana membelokkan interupsi
05h(PrtScr) ke interupsi 1Bh. Interupsi 1Bh yaitu suatu interupsi yang akan
selalu terjadi bila kita menekan tombol Ctrl+Break. sehingga sesudah
program "breaks" dijalankan, penekanan tombol PrtScr akan seperti dengan
penekanan tombol Ctrl+Break.
Arah_Vec MACRO NoInt,Alamat
MOV AX,Alamat[2]
MOV DS,AX ; DS = segment
MOV DX,Alamat ; DX = offset
MOV AH,25h ; Servis untuk merubah vektor
MOV AL,NoInt ; No interupsi
INT 21h
ENDM
Ambil_Vec MACRO NoInt,Alamat
MOV AH,35h ; Servis untuk mencari vektor
MOV AL,NoInt ; No inteurpsi
INT 21h ; lakukan
MOV Alamat,BX ; Offset
MOV Alamat[2],ES ; Segment
ENDM
;/====================/;
.MODEL SMALL
.CODE
ORG 100h
TData : JMP Res_kan
Break EQU 23h
PrtScr EQU 05
Addr_Break DW ?,? ; Untuk menyimpan Alamat
; vektor Ctrl Break
Res_Kan :
Ambil_Vec Break,Addr_Break ; Anbil alamat Ctrl+C
Arah_Vec PrtScr,Addr_Break ; Rubah vektor PrtScr
INT 20h
END TData
program 24.1. Mengganti fungsi PrtScr menjadi Ctrl+Break
Bila progrm 24.1. dijalankan, maka tombol PrtScr sudah tidak akan
berfungsi seperti biasanya, namun berfungsi seperti penekanan tombol Ctrl
Break.
Pada waktu pelajar menyalakan komputer, ia mencari sistem operasi di drive
A: ataupun C: ,lalu memasukkannya kedalam memori bawah. Selanjutnya sistem
akan terus berada disitu dan apabila pelajar menjalankan program aplikasi
contoh game maka program itu akan disimpan di atas sistem operasi,
sehingga sistem operasi tetap ada walaupun pelajar sedang menjalankan game
itu . Inilah yang dinamakan residen, yaitu program yang tetap tinggal di
memori.
Dalam contoh pelajar ini bila game tadi sudah selesai maka ia akan lenyap
dari memori dan bila pelajar menjalankan program aplikasi lainnya, contoh WS
maka tempat memori yang dipakai oleh game pelajar akan dipakai oleh WS. Ini
yaitu contoh dari program yang tidak residen sebab ia hanya sementara waktu
berada di memori. Contoh program residen yang terkenal contoh SideKick,
Print(dos) dan Doskey.
+------------------+ +------------------+
| (USER AREA RAM) | | (USER AREA RAM) |
| | | |
| program | | program |
| APLIKASI 1 | | APLIKASI 2 |
| GAME | | WS |
+------------------+ +------------------+
| OPERATING SYSTEM | | OPERATING SYSTEM |
+------------------+ +------------------+
gambar kode 24.1. Peta RAM tanpa program Residen
program residen yaitu program yang akan menetap dimemory seperti halnya
DOS dan program residen ini akan berada tepat diatas Operating System. program
residen akan dianggap sebagai bagian dari Operating System sehingga bila
dijalankan program aplikasi maka program aplikasi itu akan ditaruh diatas
program residen sehingga program residen pelajar tetap utuh.
+------------------+ +------------------+
| (USER AREA RAM) | | (USER AREA RAM) |
| | | |
| program | | program |
| APLIKASI 1 | | APLIKASI 2 |
| GAME | | WS |
+------------------+ +------------------+
| RESIDENT SECTION | | RESIDENT SECTION |
+------------------+ +------------------+
| OPERATING SYSTEM | | OPERATING SYSTEM |
+------------------+ +------------------+
gambar kode 24.2. Peta RAM dengan program residen
program residen yaitu suatu bentuk program yang menarik. sebab program
residen menetap pada memory, maka semakin banyak program residen dijalankan,
memory akan semakin berkurang untuk dipakai oleh program aplikasi. program
residen, haruslah dibuat sekecil mungkin untuk menghindari pemakaian memory
yang terlalu banyak. Hanya dengan Assembler-lah, sebuah program dapat dibuat
sekecil mungkin! Bayangkan, program untuk menghapus layar, dengan bahasa
tingkat tinggi seperti pada pascal dan C dipakai sepelajar r 3232 byte,
sedang pada assembler sepelajar r 7 byte.
Dalam pembuatan program residen, pelajar dapat membaginya dalam 2 bagian
pokok, yaitu :
- Initialize section, yaitu bagian dari program yang bertugas meresidenkan
residen section. Bagian ini sendiri tidak residen, dan pada bagian inilah
suatu vektor interupsi diubah.
- Residen section, yaitu bagian program yang akan menetap pada memory. program
ini akan tetap tinggal pada memory sampai dihilangkan, atau sampai komputer
direset.
Pada program sebelumnya, pelajar selalu mengakhiri program dengan interupsi
20h yang akan mengembalikan kontrol program sepenuhnya pada DOS. Pada program
residen, program akan selalu pelajar akhiri dengan interupsi 27h ataupun
interupsi 21h fungsi 31h. Untuk memakai interupsi 27h, pelajar tinggal
mengisi pasangan register DS:DX dengan batas memory yang akan diresidenkan.
+------------------+
| |
| |
| USER AREA RAM |
| |
| |
+------------------+<--DS:DX
| RESIDENT SECTION |
+------------------+
| OPERATING SYSTEM |
+------------------+
gambar kode 24.3. pemakaian interupsi 27h untuk meresidenkan program
Untuk membuat program residen, kita bisa memakai bentuk program
seperti pada gambar kode 24.4.
----------------------------------------------------------------
.MODEL SMALL
.CODE
ORG 100h
TData : JMP Res_kan
+------------------+
| Tempat untuk |
| mengartikan |
| DATA |
+------------------+
Bag_Res PROC
PUSH AX ;
PUSH BX ;
PUSH CX ;
PUSH DX ;
PUSH ES ; Simpan isi semua register
PUSH DI ;
PUSH DS ;
(159)
PUSH SI ;
+------------------+
| Tempat handler |
| interupsi yang |
| baru |
+------------------+
POP SI ;
POP DS ;
POP DI ;
POP ES ;
POP DX ; Kembalikan isi semua register
POP CX ;
POP BX ;
POP AX ;
IRET ; Akhir dari interupt handler
Bag_Res ENDP
Res_Kan :
+------------------+
| Tempat untuk |
| memanipulasi |
| vektor interupsi |
+------------------+
LEA DX,Res_Kan
INT 27h
END TData
----------------------------------------------------------------
gambar kode 24.4. Model program Residen
24.6. program RESIDEN PERTAMA
Pada program berikut akan pelajar lihat bagaimana membelokkan merubah
vektor interupsi PrtScr menuju program pelajar . Dengan cara yang sama kita bisa
membelokkan vektor interupsi yang lain, dan membuat suatu handler yang baru
untuknya.
;/=======================/;
.MODEL SMALL
.CODE
ORG 100h
TData : JMP Res_kan
Pesan DB ' Interupsi 5<PrtScr> sudah di belokkan !! '
NoInt EQU 05h
Bag_Res PROC
PUSH AX ;
PUSH BX ;
PUSH CX ;
PUSH DX ;
PUSH ES ; Simpan isi semua register
PUSH DI ;
PUSH DS ;
PUSH SI ;
MOV AX,1300h ;
MOV BL,01001111b ;
MOV BH,00 ;
MOV DL,20 ;
MOV DH,12 ; program interupt handler PrtScr
MOV CX,44 ; yang baru.
PUSH CS ;
POP ES ;
LEA BP,Pesan ;
INT 10h ;
POP SI ;
POP DS ;
POP DI ;
POP ES ;
POP DX ; Kembalikan isi semua register
POP CX ;
POP BX ;
POP AX ;
IRET ; Akhir dari interupt handler
Bag_Res ENDP
Res_Kan :
MOV AH,25h ;
MOV AL,NoInt ; Untuk merubah vektor interupsi
LEA DX,Bag_Res ; 05 menuju 'Bag_Res'
INT 21h ;
LEA DX,Res_Kan ;
INT 27h ; Untuk meresidenkan bagian
END TData ; "Bag_Res"
program 24.2. Membuat program Residen
Bila program 24.2. dijalankan, maka tombol PrtScr sudah tidak akan
berfungsi lagi. Setiap kali tombol PrtScr ditekan, pada posisi 20,12 akan
ditampilkan pesan:
Interupsi 5<PrtScr> sudah di belokkan !!
lihat , bahwa pada program ini ada 2 bagian pokok, yaitu
bagian yang residen dan bagian yang meresidenkan. Bagian yang meresidenkan
hanya dijalankan sekali, sedang bagian yang residen akan dijalankan setiap
kali terjadi penekanan tombol PrtScr. Bagian yang meresidenkan yaitu:
Res_Kan :
MOV AH,25h ;
MOV AL,NoInt ; Untuk merubah vektor interupsi
LEA DX,Bag_Res ; 05 menuju 'Bag_Res'
INT 21h ;
LEA DX,Res_Kan ;
INT 27h ; Untuk meresidenkan bagian
END TData ; "Bag_Res"
Bagian ini tugasnya meresidenkan bagian Bag_Res. Sebelum bagian Bag_Res
diresidenkan, vektor interupsi PrtScr(05) diubah menuju progam Bag_Res. Bila
kita hanya merubah interupsi PrtScr menuju program Bag_Res tanpa diresidenkan,
maka akan memicu komputer kita menjadi hang, mengapa? Walaupun vektor
interupsi tetap menunjuk pada lokasi atau alamat yang sama, namun tempat yang
dipakai program pelajar sudah diserahkan kepada Dos untuk dipakai oleh
aplikasi lain.
Bag_Res PROC
PUSH AX ;
PUSH BX ;
PUSH CX ;
PUSH DX ;
PUSH ES ; Simpan isi semua register
PUSH DI ;
PUSH DS ;
PUSH SI ;
Ini yaitu awal dari bagian yang residen. Simpanlah semua nilai register
pada awal program residen untuk mencegah terganggunya program lain yang sedang
berjalan pada saat tombol PrtScr ditekan.
MOV AX,1300h ;
MOV BL,01001111b ;
MOV BH,00 ;
MOV DL,20 ;
MOV DH,12 ; program interupt handler PrtScr
MOV CX,44 ; yang baru.
PUSH CS ;
POP ES ;
LEA BP,Pesan ;
INT 10h ;
Bagian ini dapat dikatakan sebagai handler baru bagi interupsi PrtScr.
Tombol PrtScr yang biasanya mencetak tampilan layar pada printer akan berubah
menjadi mencetak pesan pada layar. sehingga kita bisa membuat handler
baru yang akan melakukan sesuatu setiap kali terjadi penekanan tombol PrtScr.
lihat ! :
untuk mencetak pesan pada layar dipakai interupsi 10h, dan bukannya
interupsi Dos fungsi 09 yang biasanya pelajar pakai . Mengapa demikian ?
Sebagian besar Interupsi Dos tidak bisa dipakai pada program residen, sebab
sifat dari Dos yang tidak reentrant. Masalah ini akan pelajar bicarakan lebih
lanjut nantinya.
POP SI ;
POP DS ;
POP DI ;
POP ES ;
POP DX ; Kembalikan isi semua register
POP CX ;
POP BX ;
POP AX ;
IRET ; Akhir dari interupt handler
Bag_Res ENDP
Pada akhir program residen, kembalikanlah nilai semua register yang
disimpan, ditambah perintah IRET(Interrupt Return). Perintah IRET akan
mengambil alamat CS dan IP dan nilai Flag pada stack untuk kembali menuju
program yang diselanya. CS, IP dan nilai flag disimpan pada stack pada saat
terjadi interupsi, inilah rahasianya mengapa program dapat berjalan normal
kembali sesudah memperoleh interupsi.
Pada alamat 40h:17h ada data tentang status tombol keyboard yang mana
bit ke 7 dipakai untuk mengartikan keadaan dari tombol caps lock. Bit
itu akan bernilai 1 bila caps lock sedang aktif dan 0 bila caps lock
tidak aktif. Dengan mengubah bit ke 7 pada alamat 40h:17h itu pelajar bisa
menyalakan tombol caps lock tanpa menekannya.
Aksi MACRO
MOV AX,40h
MOV ES,AX ; ES=40h
MOV AX,ES:[17h] ; AX=40h:17h
OR AX,01000000b ; Jadikan bit ke 7 menjadi 1
MOV ES:[17h],AX ; Masukkan kembali ke 40h:17h
ENDM
;/==================/;
.MODEL SMALL
.CODE
ORG 100h
TData : JMP Res_kan
NoInt EQU 1Ch
Bag_Res PROC
PUSH AX ;
PUSH BX ;
PUSH CX ;
PUSH DX ;
PUSH ES ; Simpan isi semua register
PUSH DI ;
PUSH DS ;
PUSH SI ;
Aksi
POP SI ;
POP DS ;
POP DI ;
POP ES ;
POP DX ; Kembalikan isi semua register
POP CX ;
POP BX ;
POP AX ;
IRET ; Akhir dari interupt handler
Bag_Res ENDP
Res_Kan :
MOV AH,25h ;
MOV AL,NoInt ; Untuk merubah vektor interupsi
LEA DX,Bag_Res ; 1Ch menuju 'Bag_Res'
INT 21h ;
LEA DX,Res_Kan ;
INT 27h ; Untuk meresidenkan bagian
END TData ; 'Bag_Res'
program 24.3. Mengunci Caps Lock
Pada program pelajar kali ini yang dibelokkan yaitu interupsi 1Ch. Handler
Interupsi ini secara defaultnya hanyalah berisi perintah IRET sebab interupsi
ini memang disediakan untuk dipakai oleh pemakai.
Interupsi 1Ch terjadi kurang lebih 18,2 kali setiap detiknya. sebab nya
dengan memakai interupsi 1Ch ini penekanan tombol Caps Lock menjadi
seakan-akan tidak berarti lagi sebab selalu dinyalakan oleh program pelajar .
Pada assembler ada suatu tipe data yang istimewa, yaitu
pendefinisian data melalui perintah LABEL, dengan syntax:
Nama LABEL TipeData
Pendefinisian data dengan DB, DW, DD, DF, DQ dan DT akan memicu
assembler menyediakan suatu tempat khusus. contoh kita mengartikan suatu
data dengan "A DW ?", maka assembler akan menyediakan 2 byte di memory
untuknya. kita hanya dapat memakai 2 byte pada memory melalui variabel
"A".
Dengan pemakaian label, assembler akan menyediakan memory dimulai dari
lokasi pendefinisiannya sampai sebatas memory kita . Selain itu pemakaian
Label tidak memakai memory khusus. Pada program 24.4, program COM yang
dihasilkan memakai memory 26 byte. Bila pemakaian label dihilangkan dan
pengisian angka untuk variabel A,B dan C dilakukan secara langsung, memory
yang dipakai oleh pada program 24.4. juga 26 byte!.
;/===================/;
.MODEL SMALL
.CODE
ORG 100h
TData : JMP Proses
XX LABEL BYTE
A DB 1
B DB 2
C DB 3
Proses:
MOV XX[0],0Ah ; = MOV A,0Ah
MOV XX[1],0Bh ; = MOV B,0Bh
MOV XX[2],0Ch ; = MOV C,0Bh
(163)
INT 20h
END TData
program 24.4. pemakaian LABEL
sebab pelajar mengartikan "XX label byte" diatas variabel A, maka byte
pertama dari "XX" akan sama dengan variabel "A", byte keduanya sama dengan "B"
dan byte ketiganya sama dengan "C". sehingga perintah "MOV XX[0],0Ah"
yaitu identik dengan "MOV A,0Ah".
+-XX+---+---+---+---
+---+---+---+---+---
| 1 | 2 | 3 | |
+---+---+---+---+---
"A" "B" "C"
Dengan pemakaian label ini, pelajar bisa mengakses suatu tempat di memory
dengan memakai 2 atau lebih nama yang berlainan. Apa kelebihan lainnya ?
- Dengan mengartikan suatu variabel label pada akhir program , maka akan
diperoleh suatu variabel penampung yang besar sekali, tanpa harus
memperbesar program .
- Dengan pendefinisian label juga dimungkinkan pengaksesan data dengan tipe
data yang berlainan pada variabel. agar lebih jelas, bisa kita lihat pada
program berikut ini:
;/=================/;
.MODEL SMALL
.CODE
ORG 100h
TData : JMP Proses
XX LABEL WORD
A DB 1,2
Proses:
MOV XX,0Ah ;=> A[0]=0Ah Dan A[1]=00
INT 20h
END TData
program 24.5. Merubah tipe data dengan Label
Pada program 24.5. dapat dilihat bahwa pelajar bisa saja mengakses nilai
pada variabel A yang didiartikan dengan tipe data byte diakses dengan tipe
data word. sehingga pemakaian label memungkinkan pelajar untuk mengakses
suatu data dengan tipe data yang berbeda.
+--XX---+-------+---
+---+---+---+---+---
| 1 | 2 | | |
+---+---+---+---+---
A[0] A[1]
24.9. MEMANGGIL HANDLER INTERUPSI LAMA
Pada program yang mengganti handler interupsi, kadang-kadang pelajar masih
ingin melakukan handler yang asli. Untuk itu lihatlah pada program 24.6.
berikut:
Cetak_Pesan MACRO Pesan,Banyak,X,Y
MOV AX,1300h ; Fungsi untuk mencetak kalimat
MOV BL,01001111b ; Atribut
MOV BH,00 ; Nomor halaman
MOV DL,X ; Posisi kolom
MOV DH,Y ; Posisi baris
MOV CX,Banyak ; Banyaknya huruf
PUSH CS ; ES:BP mencatat +
POP ES ; lokasi kalimat
LEA BP,Pesan ;
INT 10h ; lakukan
ENDM
Readkey MACRO ; Macro untuk menunggu penekanan
MOV AH,00 ; sembarang tombol dari keyboard
INT 16h ;
ENDM
Ambil_Vec MACRO NoInt,Alamat
MOV AH,35h ; Servis untuk mencari vektor
MOV AL,NoInt ; No interupsi
INT 21h ; lakukan
MOV Alamat,BX ; Offset
MOV Alamat[2],ES ; Segment
ENDM
;/==========================/;
.MODEL SMALL
.CODE
ORG 100h
TData : JMP Res_kan
PrtScr EQU 05
Addr_PrtScr_Asli LABEL DWORD
Addr_PrtScr DW ?,?
Pesan1 DB '--> Siapkan printer kita !! Tekan'
DB ' sembarang tombol untuk mulai'
DB ' mencetak <--'
Pesan2 DB '>> PrtScr sudah dilakukan ,'
DB 'semoga kita puas dengan hasilnya <<'
Bag_Res PROC
PUSH AX ;
PUSH BX ;
PUSH CX ;
PUSH DX ;
PUSH ES ; Simpan isi semua register
PUSH DI ;
PUSH DS ;
PUSH SI ;
Cetak_Pesan Pesan1,80,0,12
Readkey
PUSHF
CALL Addr_PrtScr_Asli ; Panggil handler PrtScr
; yang asli
Cetak_Pesan Pesan2,65,5,14
POP SI ;
POP DS ;
POP DI ;
POP ES ;
POP DX ; Kembalikan isi semua register
POP CX ;
POP BX ;
POP AX ;
IRET ; Akhir dari interupt handler
Bag_Res ENDP
Res_Kan :
Ambil_Vec PrtScr,Addr_PrtScr
MOV AH,25h ;
MOV AL,PrtScr ; Membelokkan vektor interupsi
LEA DX,Bag_Res ;
INT 21h ;
LEA DX,Res_Kan ; Meresidenkan program Bag_Res
INT 27h
END TData
program 24.6. Teknik memanggil handler interupsi yang asli
Bila program 24.6. dijalankan, maka setiap penekanan tombol PrtScr,
komputer akan menampilkan pesan:
---> Siapkan printer kita !!
Tekan sembarang tombol untuk mulai mencetak <---
Komputer akan segera mencetak isi layar pada printer bila ditekan
sembarang tombol. Pencetakan dilakukan dengan memanggil interrupt handler
PrtScr yang asli dengan:
PUSHF
CALL Addr_PrtScr_Asli
Kedua perintah ini mensimulasikan perintah interrupt. Seperti yang sudah
pelajar ketahui, setiap interrupt handler selalu diakhiri dengan perintah IRET
yang akan mengambil CS, IP dan Flags dari stack. sebab perintah Call hanya
akan menyimpan CS dan IP dalam stack maka pelajar perlu menyimpan flags dalam
stack secara manual. Pada variabel "Addr_PrtScr_Asli" pelajar mengartikan nya
sebagai label Double Word sehingga kedua word variabel "Addr_PrtScr" dapat
diakses dengan tipe data Double Word(alamat CS dan IP).
Pada saat pertama DOS diciptakan, ia dirancang dengan system single
user, sehingga DOS sering dinamakan "non-reentrant operating system".
Bila terjadi interupsi dari DOS sementara interupsi DOS yang lainnya sedang
aktif, data-data yang tersimpan dalam stack akan menjadi berantakan dan
komputer akan menjadi hang. Inilah sebabnya, mengapa pada program residen
interupsi dari DOS tidak bisa dipakai . namun DOS menyediakan banyak fungsi
yang sangat berguna dan tidak ada pada fungsi BIOS, seperti penanganan
operasi pada file, memory dan sebagainya. Banyak pelajar yang mengira bahwa
interupsi DOS tidak boleh sama sekali dipakai dalam program residen. Benarkah
demikian ? Tidak.
,, interupsi DOS tidak boleh terjadi
bersamaan, sehingga untuk memakai fungsi DOS pada program residen yang
perlu pelajar lakukan yaitu " Jangan memakai fungsi DOS bila fungsi DOS yang
lain sedang aktif ". Bagaimana pelajar bisa mengetahui bahwa suatu fungsi DOS
sedang aktif atau tidak ? Untuk itu kita bisa memakai kedua cara berikut:
1. pakai fungsi 34h dari interupsi 21h untuk memperoleh InDOS Flag atau
Bendera Aktif DOS(BAD). Untuk memakai fungsi ini, masukkan 34h pada
AH, lalu lakukan interupsi 21h. Sesudah interupsi dilakukan ,
pasangan register ES:BX akan mencatat alamat tempat BAD berada. BAD yang
terdiri atas 1 byte akan bernilai nol(0) bila fungsi DOS tidak ada yang
sedang aktif. Artinya pada keadaan ini pelajar bisa memakai fungsi DOS
pada program residen dengan aman. Bila BAD bernilai lebih dari 0, artinya
ada fungsi DOS yang sedang aktif. Dalam keadaan seperti ini pelajar
tidak boleh memakai fungsi DOS pada program residen, sebab akan
meyebabkan komputer menjadi hang.
2. DOS mungkin saja dalam keadaan aman, walaupun BAD bernilai lebih dari
0(biasanya 1). Untuk mengartikan keadaan aman ini DOS akan selalu
mengaktifkan interupsi 28h. Handler asli dari interupsi 28h ini hanyalah
berupa perintah IRET. Bila interupsi 28h ini diaktifkan, pelajar bisa
memakai fungsi DOS dengan aman pada program residen. Interupsi 28h ini
biasanya diaktifkan DOS pada saat DOS sedang menunggu masukan dari
keyboard dengan fungsi 01h-0Ch. Untuk memakai interupsi ini, buatlah
suatu handler baru untuknya.
Pada program 24.7. akan ditunjukkan bagaimana interupsi dari DOS, yaitu
interupsi 21h fungsi 09h dipakai pada program residen. Dengan teknik yang
sama, kita bisa memakai segala fungsi dari interupsi DOS dalam program
residen tanpa perlu takut program kita menjadi hang.
Cetak_Pesan MACRO Pesan ; Mencetak kalimat dengan
MOV AH,09 ; interupsi dari DOS
PUSH CS ;
POP DS ; Samakan nilai CS dan DS
LEA DX,Pesan ;
INT 21h ; Interupsi DOS
ENDM
Ambil_Vec MACRO NoInt,Alamat
MOV AH,35h ; Servis untuk mencari vektor
MOV AL,NoInt ; No interupsi
INT 21h ; lakukan
MOV Alamat,BX ; Offset
MOV Alamat[2],ES ; Segment
ENDM
;/============/;
.MODEL SMALL
.CODE
ORG 100h
TData : JMP Res_kan
PrtScr EQU 05
Addr_PrtScr_Asli LABEL DWORD
Addr_PrtScr DW ?,?
Pesan DB ' Kalimat ini dicetak dengan fungsi'
DB ' dari DOS. ',13,10
DB ' Pemecahan masalah '
DB 'Reentrancy DOS !!!$'
Offset_BAD DW ?
Segmen_BAD DW ?
Res05 PROC
PUSH AX ;
PUSH BX ;
PUSH CX ;
PUSH DX ;
PUSH ES ; Simpan isi semua register
PUSH DI ;
PUSH DS ;
PUSH SI ;
MOV AX,Segmen_BAD
MOV ES,AX
MOV BX,Offset_BAD ; ES:BX = alamat BAD
CMP BYTE PTR ES:[BX],0 ; Apakah ada fungsi DOS yang
; sedang aktif?
JNE Pulihkan ; Ya, jangan lakukan
Aman : ; interupsi DOS
Cetak_Pesan Pesan ; Tidak, lakukan interupsi DOS
Pulihkan:
POP SI ;
POP DS ;
POP DI ;
POP ES ;
POP DX ; Kembalikan isi semua register
POP CX ;
POP BX ;
POP AX ;
IRET ; Akhir dari interupt handler
Res05 ENDP
Res_Kan :
Ambil_Vec PrtScr,Addr_PrtScr
MOV AH,25h ;
MOV AL,PrtScr ; Membelokkan vektor interupsi
LEA DX,Res05 ;
INT 21h ;
MOV AH,34h ;
INT 21h ; Ambil alamat InDOS flag
MOV Segmen_BAD,ES ; atau BAD
MOV Offset_BAD,BX ;
LEA DX,Res_Kan ; Meresidenkan program Bag_Res
INT 27h
END TData
program 24.7. memakai fungsi DOS dalam program Residen
Bila program 24.7. dijalankan, maka setiap kali terjadi penekanan
pada tombol PrtScr, program akan melihat keadaan aman atau tidak untuk
memakai interupsi DOS. Bila BAD bernilai nol atau keadaan aman, program
akan mencetak kalimat dengan fungsi dari DOS. Pesan yang tercetak yaitu:
Kalimat ini dicetak dengan fungsi dari DOS.
Pemecahan masalah Reentrancy DOS !!!
Bila BAD bernilai lebih dari nol atau keadaan tidak aman, program tidak
memakai fungsi dari DOS dan akan segera keluar.
Pada modus text, layar dibagi menjadi kotak-kotak yang membentuk
huruf . Pada modus default Dos, layar terbagi menjadi 80 kotak horisontal
dan 25 kotak vertical. pelajar bisa saja membentuk suatu gambar kode pada modus teks,
akan namun hasilnya tentu saja sangat kasar.
Pada modus grafik, layar dibagi menjadi titik-titik yang dinamakan sebagai
Pixel. Untuk memrogram pada modus grafik ini, tentunya kita harus mengaktifkan
mode layar grafik terlebih dahulu (Lihat 18.10 tentang mode layar). contoh
kita mengaktifkan mode 13h, maka layar akan dibagi menjadi 320 X 200 pixel,
atau sama dengan 64000 titik. Bila diaktifkan mode 06h, maka layar akan dibagi
menjadi 640 X 200 pixel atau sama 128000 pixel. Tentunya pada mode 06 ini
gambar kode akan tampak lebih halus. kita harus ingat bahwa tidak semua mode
didukung oleh monitor kita . kita harus mengetahui dengan jelas jenis monitor
dan modus apa saja yang didukungnya.
Bila kita memakai komputer, seperti Hercules dan Macintosh maka
dengan mudah kita dapat menggambar kode lingkaran, garis, dan mewarnai gambar
itu . Bagaimana pada komputer IBM PC dan kompatiblenya?
Pada komputer IBM PC dan kompatiblenya, kemampuan menggambar kode pada modus
grafik hanyalah satu, yaitu menggambar kode pixel(titik). Kemampuan ini tampaknya
sangatlah kurang, namun pada bagian ini akan pelajar lihat bagaimana memakai
fasilitas ini untuk menggambar kode berbagai gambar kode yang menarik.
Untuk menggambar kode pixel ini aktifkanlah modus grafik terlebih dahulu.
Sesudah itu kita bisa menggambar kode pixel dengan fungsi 0Ch, dengan aturan
pemakaian:
INPUT:
AH = 0Ch
AL = Atribut dari pixel. bila bit ke 7-nya 1, maka pixel akan
di Xor dengan gambar kode layar.
CX = Posisi kolom(X) tempat pixel akan digambar kode
DX = Posisi baris(Y) tempat pixel akan digambar kode
BH = Nomor halaman, bila modus video yang dipakai memiliki
halaman tampilan melebihi satu. bila modus yang dipakai
hanya memakai 1 halaman tampilan, maka isi BH akan
diabaikan.
Sesudah semuanya kita persiapkan, lakukan lah interupsi 10h. Contoh
dari macro untuk menggambar kode pixel:
Pixel MACRO X,Y,Warna
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV AH,0Ch
MOV CX,X ; Posisi kolom atau X
MOV DX,Y ; Posisi baris atau Y
MOV AL,Warna ; Atribut Pixel
INT 10h ; gambar kode pixel itu !
POP DX
POP CX
POP BX
POP AX
ENDM
Kebalikan dari fungsi 0Ch, fungsi 0Dh dari interupsi 10h dipakai untuk
memperoleh warna dari suatu pixel. Aturan untuk memakai fungsi ini
yaitu:
INPUT:
AH = 0Dh
CX = Posisi kolom(X) dari pixel
DX = Posisi baris(Y) dari pixel
BH = Nomor halaman, bila modus video yang dipakai memiliki
halaman tampilan melebihi satu. bila modus yang dipakai
hanya memakai 1 halaman tampilan, maka isi BH akan
diabaikan.
OUTPUT:
AL = Atribut dari pixel pada kolom CX dan baris DX.
Bila suatu benda dibagi-bagi terus, maka akan kita dapatkan apa yang
dinamakan sebagai atom, atau bagian terkecil dari suatu benda. Demikian halnya
pada gambar, bila dilihat secara seksama, setiap gambar kode terbentuk atas titiktitik. Makin banyak titik yang membentuk suatu gambar, makin haluslah gambar kode
itu . Dengan prinsip yang sama, pelajar bisa membuat bermacam gambar kode yang
menarik.
- Untuk menggambar kode garis vertical atau horisontal yaitu cukup mudah. kita
hanya perlu menggambar kode titik-titik secara berurutan untuk menghasilkan sebuah
garis.
- Untuk menggambar kode garis Vertical ke bawah, kita hanya perlu menambah posisi
baris(Y) dengan posisi kolom(X) yang tetap. sedang untuk menggambar kode garis
Horisontal ke kanan, kita hanya perlu menambah posisi kolom(X) dengan posisi
baris(Y) yang tetap(Lihat program 25.1).
Readkey MACRO
MOV AH,00
INT 16h
ENDM
SetCRT MACRO Mode
MOV AH,00
MOV AL,Mode
INT 10h
ENDM
PutPixel MACRO X,Y,Warna
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV AH,0C ; Servis menggambar kode pixel
MOV CX,X ; Posisi kolom atau X
MOV DX,Y ; Posisi baris atau Y
MOV AL,Warna ; Atribut Pixel
INT 10h ; gambar kode pixel itu !
POP DX
POP CX
POP BX
POP AX
ENDM
GarisV MACRO X1,Y1,Panjang,Warna
LOCAL Ulang
PUSH DX
PUSH CX
MOV DX,Y1
MOV CX,Panjang
Ulang:
PutPixel X1,DX,Warna
INC DX
LOOP Ulang
POP CX
POP DX
ENDM
GarisH MACRO X1,Y1,Panjang,Warna
LOCAL Ulang
PUSH CX
PUSH DX
MOV DX,X1
MOV CX,Panjang
Ulang:
PutPixel DX,Y1,Warna
INC DX
LOOP Ulang
POP DX
POP CX
ENDM
;/===========/;
.MODEL SMALL
.CODE
ORG 100h
Proses:
SetCRT 13h ; Aktifkan mode grafik 13h
GarisV 150,50,50,12 ; gambar kode garis Vertikal
Readkey ; Tunggu penekanan keyboard
GarisH 135,60,30,12 ; gambar kode garis Horisontal
Readkey ; Tunggu penekanan keyboard
SetCRT 03h ; Kembali pada mode Dos
INT 20h
END Proses
program 25.1. Menggambar kode garis Vertical dan Horisontal
Bila program 25.1. dieksekusi, maka pada layar akan ditampilkan sebuah
gambar kode salib yang terdiri atas garis vertical dan horisontal.
<<<< Gbr251.PIX >>>>
gambar kode 25.1. Hasil eksekusi program 25.1.
Untuk menggambar kode sebuah garis miring, prinsip yang dipakai tidak
jauh berbeda dengan menggambar kode garis lurus. Untuk menggambar kode sebuah garis
miring 45 derajat ke kiri bawah, kita hanya perlu menggambar kode pixel sambil
mengurangi posisi kolom(X) dan menambah posisi baris(Y). sedang untuk
menggambar kode sebuah garis miring 45 derajat ke kanan bawah, kita bisa menggambar kode
pixel sambil menambahi posisi kolom(X) dan menambah posisi baris(Y).
Readkey MACRO
MOV AH,00
INT 16h
ENDM
SetCRT MACRO Mode
MOV AH,00
MOV AL,Mode
INT 10h
ENDM
PutPixel MACRO X,Y,Warna
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV AH,12 ; Servis menggambar kode pixel
MOV CX,X ; Posisi kolom atau X
MOV DX,Y ; Posisi baris atau Y
MOV AL,Warna ; Atribut Pixel
INT 10h ; gambar kode pixel itu !
POP DX
POP CX
POP BX
POP AX
ENDM
M_Kanan MACRO X1,Y1,Panjang,Warna
LOCAL Ulang
PUSH BX
PUSH CX
PUSH DX
MOV DX,X1
MOV BX,Y1
MOV CX,Panjang
Ulang:
PutPixel DX,BX,Warna
INC DX
INC BX
LOOP Ulang
POP DX
POP CX
POP BX
ENDM
M_Kiri MACRO X1,Y1,Panjang,Warna
LOCAL Ulang
PUSH BX
PUSH CX
PUSH DX
MOV DX,X1
MOV BX,Y1
MOV CX,Panjang
Ulang:
PutPixel DX,BX,Warna
DEC DX
INC BX
LOOP Ulang
POP DX
POP CX
POP BX
ENDM
;/=========================/;
.MODEL SMALL
.CODE
ORG 100h
Proses:
SetCRT 13h
M_Kiri 150,0,50,83 ; Garis miring kiri
Readkey
M_Kanan 150,0,50,83 ; Garis miring kanan
Readkey
SetCRT 03h
INT 20h
END Proses
program 25.2. Menggambar kode garis miring
Bila program 25.2. dieksekusi, maka pada layar akan ditampilkan sebuah
gambar kode atap rumah yang terdiri atas garis miring kekanan dan kiri.
<<<< Gbr252.PIX >>>>
gambar kode 25.2. Hasil eksekusi program 25.2.
25.6. MENGgambar kode KOTAK
Sebuah kotak terdiri atas 2 garis vertical dan 2 garis horisontal. Untuk
itu kita bisa memakai macro dari GarisV dan GarisH untuk menggambar kode kotak
ini. pelajar hanya menentukan posisi
X1,Y1 dan X2,Y2(gambar kode 25.3) untuk menggambar kode sebuah kotak. Perhatikan, bahwa
X2 > X1 dan Y2 > Y1.
X1,Y1+-----------------------+X2,Y1
| X2-X1 |
| |
| |
|Y2-Y1 Y2-Y1|
(175)
| |
| |
| X2-X1 |
X1,Y2+-----------------------+X2,Y2
gambar kode 25.3. Teknik menggambar kode kotak
Dari gambar kode 25.3. dapat kita lihat, dengan mudah sebuah kotak dapat
digambar kode dengan bantuan macro untuk menggambar kode garis vertikal dan horisontal.
Readkey MACRO
MOV AH,00
INT 16h
ENDM
SetCRT MACRO Mode
MOV AH,00
MOV AL,Mode
INT 10h
ENDM
PutPixel MACRO X,Y,Warna
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV AH,0C ; Servis menggambar kode pixel
MOV CX,X ; Posisi kolom atau X
MOV DX,Y ; Posisi baris atau Y
MOV AL,Warna ; Atribut Pixel
INT 10h ; gambar kode pixel itu !
POP DX
POP CX
POP BX
POP AX
ENDM
GarisV MACRO X1,Y1,Panjang,Warna
LOCAL Ulang
PUSH DX
PUSH CX
MOV DX,Y1
MOV CX,Panjang
Ulang:
PutPixel X1,DX,Warna
INC DX
LOOP Ulang
POP CX
POP DX
ENDM
GarisH MACRO X1,Y1,Panjang,Warna
LOCAL Ulang
PUSH CX
PUSH DX
MOV DX,X1
MOV CX,Panjang
Ulang:
PutPixel DX,Y1,Warna
INC DX
LOOP Ulang
POP DX
POP CX
ENDM
Kotak MACRO X1,Y1,X2,Y2,Warna
GarisH X1,Y1,X2-X1,Warna
GarisV X1,Y1,Y2-Y1,Warna
GarisV X2,Y1,Y2-Y1,Warna
GarisH X1,Y2,X2-X1+1,Warna
ENDM
;/================/;
.MODEL SMALL
.CODE
ORG 100h
Proses:
SetCRT 13h
Kotak 120,30,180,100,12 ; gambar kode kotak
Readkey
SetCRT 03h
INT 20h
END Proses
program 25.3. Menggambar kode Kotak
Bila program 25.3. dieksekusi, maka pada layar akan ditampilkan sebuah
gambar kode kotak persegi empat(gambar kode 25.4).
<<<< Gbr254.PIX >>>>
gambar kode 25.4. Hasil eksekusi program 25.3.
Pada program 25.3., pelajar hanya sekedar menggambar kode sebuah kotak tanpa
warna dasar. Untuk memberi warna pada kotak pelajar harus menggambar kode pixel-pixel
pada seluruh area kotak yang kosong. sehingga kotak akan menjadi
berwarna.
Untuk menggambar kode area kotak ini, bisa kita pakai bermacam-maca cara,
contoh dengan menggambarkan garis vertical ataupun garis horisontal. Pada
program 25.4. pelajar akan mewarnai area yang kosong pada kotak dengan dengan
garis-garis Horisontal.
Readkey MACRO
MOV AH,00
INT 16h
ENDM
SetCRT MACRO Mode
MOV AH,00
MOV AL,Mode
INT 10h
ENDM
PutPixel MACRO X,Y,Warna
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV AH,12 ; Servis menggambar kode pixel
MOV CX,X ; Posisi kolom atau X
MOV DX,Y ; Posisi baris atau Y
MOV AL,Warna ; Atribut Pixel
INT 10h ; gambar kode pixel itu !
POP DX
POP CX
POP BX
POP AX
ENDM
GarisV MACRO X1,Y1,Panjang,Warna
LOCAL Ulang
PUSH DX
PUSH CX
MOV DX,Y1
MOV CX,Panjang
Ulang:
PutPixel X1,DX,Warna
INC DX
LOOP Ulang
POP CX
POP DX
ENDM
GarisH MACRO X1,Y1,Panjang,Warna
LOCAL Ulang
PUSH CX
PUSH DX
MOV DX,X1
MOV CX,Panjang
Ulang:
PutPixel DX,Y1,Warna
INC DX
LOOP Ulang
POP DX
POP CX
ENDM
Kotak MACRO X1,Y1,X2,Y2,Warna
GarisH X1,Y1,X2-X1,Warna
GarisV X1,Y1,Y2-Y1,Warna
GarisV X2,Y1,Y2-Y1,Warna
GarisH X1,Y2,X2-X1+1,Warna
ENDM
KotakW MACRO X1,Y1,X2,Y2,Warna
LOCAL Ulang1,Ulang2
PUSH AX
PUSH CX
MOV AX,Y1+1
MOV CX,Y2-Y1-1
Ulang1:
GarisH X1+1,AX,X2-X1-1,Warna
INC AX
LOOP Ulang1
POP CX
POP AX
ENDM
;/===================/;
.MODEL SMALL
.CODE
ORG 100h
Proses:
SetCRT 13h
Kotak 120,30,180,100,12 ; gambar kode kotak
Readkey
KotakW 120,30,180,100,09 ; Warnai kotak
Readkey
SetCRT 03h
INT 20h
END Proses
program 25.4. Mewarnai Kotak
Bila program 25.4. dieksekusi, maka pada layar akan ditampilkan sebuah
gambar kode kotak yang sudah diwarnai (gambar kode 25.5).
<<<<< Gbr255.PIX >>>>>
gambar kode 25.5. Hasil eksekusi program 25.4.
Pada program 25.4. ini, kotak akan diwarnai seluruhnya. Cobalah kita
membuat kreasi sendiri, contoh kotak akan diwarnai dengan garis-garis
vertical, garis-garis harisontal atau kotak- kotak kecil.
Pada program sebelumnya, pelajar selalu menggambar kode bentuk gambar kode yang
linear. Kini, bila kita ingin menggambar kode sebuah gambar kode tak tentu, seperti
manusia, tengkorak, tank, bunga atau helikopter, dengan rumus yaitu tidak
mungkin.
Untuk itu salah satu cara yang praktis yaitu membentuk suatu tabel
gambar. Dari tabel ini lalu kita lihat secara perBITnya. Bila bit pada
data gambar kode bernilai satu, maka gambarlah sebuah pixel, sebaliknya bila Bit
pada data gambar kode bernilai nol maka pixel tidak digambar. Sesudah itu
pindahkan posisi X(Kolom) dan test bit berikutnya.
Dengan cara demikian kita bisa membuat gambar kode dalam ukuran yang
berapapun, sesuai resolusi monitor kita . Pada program 25.5. akan ditunjukkan,
bagaimana membuat sebuah gambar kode helikopter dengan ukuran 32 bit X 32 bit.
Readkey MACRO ; Untuk menunggu masukan dari
MOV AH,00 ; Keyboard
INT 16h
ENDM
SetCRT MACRO Mode ; Untuk merubah mode layar
MOV AH,00 ;
MOV AL,Mode ;
INT 10h
ENDM
Pixel MACRO X,Y,Warna ; Untuk menggambar kode pixel
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV AH,12 ; Servis menggambar kode pixel
MOV CX,X ; Posisi kolom atau X
MOV DX,Y ; Posisi baris atau Y
MOV AL,Warna ; Atribut Pixel
INT 10h ; gambar kode pixel itu !
POP DX
POP CX
POP BX
POP AX
ENDM
;/====================/;
.MODEL SMALL
.CODE
ORG 100h
TData : JMP Proses
gambar kode DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000001110000000b
DW 0000000000000000b,0000000100000000b
DW 0000000011111111b,1111111111111110b
DW 0000000000000000b,0000000100000000b
DW 0000000000000000b,0111111111000000b
DW 1110000000000000b,1111111111100000b
DW 0100000000111111b,1111000100110000b
DW 0111111111111111b,1111000100011000b
DW 0000000000000011b,1111000111111000b
DW 0000000000000000b,0111111111100000b
DW 0000000000000000b,0010000100001000b
DW 0000000000111111b,1111111111110000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
PosX DW 100 ; Posisi awal X
PosY DW 30 ; Posisi awal Y
Proses:
SetCRT 13h ; Aktifkan mode grafik
SUB BX,BX ;
MOV CX,32 ; CX=banyaknya baris
Ulang1:
PUSH CX
MOV CX,2 ; CX=banyaknya Word dalam 1 baris
Ulang2:
PUSH CX
MOV CX,16 ; CX=Banyaknya bit dalam 1 word
MOV AX,1000000000000000b
Ulang3:
PUSH AX
AND AX,Gambar[BX] ; Test bit gambar kode yang ke AX
JZ Nol ; bila nol, lompat
Pixel PosX,PosY,83 ; bila tidak, gambar kode pixel
Nol:
POP AX ;
SHR AX,1 ;
INC PosX ; Tambah posisi X
LOOP Ulang3 ; Test bit gambar kode berikutnya
ADD BX,2 ; Akses word berikutnya
POP CX
LOOP Ulang2 ; Test word berikutnya
INC PosY ;
SUB PosX,32 ; Kembalikan posisi X mula-mula
POP CX
LOOP Ulang1 ; Test word pada baris berikutnya
Exit:
Readkey
SetCRT 03h ; Aktifkan Mode default Dos
(181)
INT 20h
END TData
program 25.5. Menggambar kode Helikopter
Bila program 25.5. dieksekusi, maka pada layar akan ditampilkan sebuah
gambar kode helikopter (gambar kode 25.6). Helikopter ini digambar kode berdasar data
gambar kode pada variabel "Gambar".
<<<<< Gbr256.PIX >>>>>
gambar kode 25.6. Hasil eksekusi program 25.5.
Catatan:
Dengan teknik yang tidak jauh berbeda, kita bisa membuat program yang
dapat menampilkan bermacam format gambar, seperti GIF, PIX, BMP, dan
sebagainya.
Pada grafik, yang paling menarik yaitu membuat sebuah animasi. Seperti
dinosaurus yang sedang berjalan, bunga yang sedang berkembang, pesawat yang
meledak dan sebagainya. Dibalik pembuatan animasi ini ada berpuluh-puluh
cara yang dapat dipakai .
Salah satu cara yang paling praktis dan mudah, walaupun tidak begitu
bagus yaitu dengan teknik gambar kode hapus. Yaitu animasi dengan cara menggambar kode
sebuah gambar, lalu dihapus dan digambar kode lagi pada posisi atau bentuk
gambar kode yang berbeda. Dengan cara ini sebuah gambar kode akan tampak seperti sedang
bergerak (program 25.6).
Delay MACRO
LOCAL Ulang
PUSH CX
SUB CX,CX
Ulang:
LOOP Ulang
POP CX
ENDM
SetCRT MACRO Mode
MOV AH,00
MOV AL,Mode
INT 10h
ENDM
Pixel MACRO X,Y,Warna
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV AH,12 ; Servis menggambar kode pixel
MOV CX,X ; Posisi kolom atau X
MOV DX,Y ; Posisi baris atau Y
MOV AL,Warna ; Atribut Pixel
INT 10h ; gambar kode pixel itu !
POP DX
POP CX
POP BX
POP AX
ENDM
Heli MACRO Gambar,Warna
LOCAL Ulang1,Ulang2,Ulang3,Nol
PUSH AX ;
PUSH BX ; Simpan semua register yang
PUSH CX ; dipakai
PUSH DX ;
SUB BX,BX ;
MOV CX,32 ; CX = banyaknya baris
Ulang1:
PUSH CX
MOV CX,2 ; CX = banyaknya Word satu baris
Ulang2:
PUSH CX
MOV CX,16 ; CX = Banyaknya bit pada 1 word
MOV AX,1000000000000000b
Ulang3:
PUSH AX
AND AX,Gambar[BX] ; Apakah bit gambar kode ke AX=1 ?
JZ Nol ; Tidak, lompat
Pixel PosX,PosY,Warna ; Ya, gambar kode pixel
Nol:
POP AX ;
SHR AX,1 ; Untuk men-test bit gambar kode
INC PosX ;
LOOP Ulang3 ; Ulangi test bit berikutnya
ADD BX,2 ; Untuk mengakses word berikutnya
POP CX ;
LOOP Ulang2 ; Ulangi test word berikutnya
INC PosY ; Tambah posisi Y
SUB PosX,32 ; Kembalikan posisi X mula-mula
POP CX ;
LOOP Ulang1 ; Test word pada baris berikutnya
SUB PosY,32 ; Kembalikan posisi Y mula-mula
POP DX ;
POP CX ; Ambil kembali semua nilai
POP BX ; register yang disimpan
POP AX ;
ENDM
;/====================/;
.MODEL SMALL
.CODE
ORG 100h
TData : JMP Proses
Heli1 DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000001110000000b
DW 0000000000000000b,0000000100000000b
DW 0000000011111111b,1111111111111110b
DW 0000000000000000b,0000000100000000b
DW 0000000000000000b,0111111111000000b
DW 1110000000000000b,1111111111100000b
DW 0100000000111111b,1111000100110000b
DW 0111111111111111b,1111000100011000b
DW 0000000000000011b,1111000111111000b
DW 0000000000000000b,0111111111100000b
DW 0000000000000000b,0010000100001000b
DW 0000000000111111b,1111111111110000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
PosX DW 00 ; Posisi awal X
PosY DW 50 ; Posisi awal Y
Proses:
SetCRT 13h ; Aktifkan mode video grafik
MOV CX,0
Ulang:
Heli Heli1,50 ; gambar kode heli dengan warna 50
Delay ;
Heli Heli1,00 ; Hapus heli dengan warna hitam
INC PosX ; Tambah posisi X
INC CX ;
CMP CX,290 ; Ulangi sebanyak 290 kali
JE Exit ;
JMP Ulang ;
Exit:
SetCRT 03h ; Kemabli ke mode video default dos
INT 20h
END TData
program 25.6. Animasi Helikopter yang sedang terbang
Bila program 25.6. dieksekusi, maka pada layar akan ditampilkan sebuah
gambar kode helikopter (gambar kode 25.6) yang akan terbang melintasi monitor kita .
Pada bagian ini, akan pelajar lihat teknik lain dalam pembuatan suatu
animasi. Seperti yang sudah kita ketahui, dalam suatu modus mungkin saja
ada beberapa halaman layar. Halaman layar ini bisa pelajar manfaatkan untuk
pembuatan suatu animasi.
Untuk itu, gambarlah bentuk gambar kode yang diinginkan pada masing-masing
halaman layar. Sesudah itu kita tinggal mengaktifkan halaman layar untuk
memperoleh suatu efek gerakan.
Readkey MACRO ; Macro untuk menuggu
PUSH AX ; penekanan tombol keyboard
MOV AH,00
INT 16h
POP AX
ENDM
Ak_Page MACRO No ; Macro ini dipakai untuk
MOV AH,5 ; mengaktifkan halaman layar
MOV AL,No
INT 10h
ENDM
SetCRT MACRO Mode ; Macro untuk mengganti mode layar
MOV AH,00
MOV AL,Mode
INT 10h
ENDM
Pixel MACRO X,Y,Warna,Hlm
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV AH,12 ; Servis menggambar kode pixel
MOV CX,X ; Posisi kolom atau X
MOV DX,Y ; Posisi baris atau Y
MOV AL,Warna ; Atribut Pixel
MOV BH,Hlm ; Halaman layar
INT 10h ; gambar kode pixel itu !
POP DX
POP CX
POP BX
POP AX
ENDM
Hallo MACRO Gambar,Warna,Hlm
LOCAL Ulang1,Ulang2,Ulang3,Nol
PUSH AX ;
PUSH BX ; Simpan semua register yang
PUSH CX ; dipakai
PUSH DX ;
SUB BX,BX ;
MOV CX,32 ; CX = banyaknya baris
Ulang1:
PUSH CX
MOV CX,2 ; CX = banyaknya Word satu baris
Ulang2:
PUSH CX
MOV CX,16 ; CX = Banyaknya bit pada 1 word
MOV AX,1000000000000000b
Ulang3:
PUSH AX
AND AX,Gambar[BX] ; Apakah bit gambar kode ke AX=1 ?
JZ Nol ; Tidak, lompat
Pixel PosX,PosY,Warna,Hlm ; Ya, gambar kode pixel
Nol:
POP AX ;
SHR AX,1 ; Untuk men-test bit gambar kode
INC PosX ;
LOOP Ulang3 ; Ulangi test bit berikutnya
ADD BX,2 ; Untuk mengakses word berikutnya
POP CX ;
LOOP Ulang2 ; Ulangi test word berikutnya
INC PosY ; Tambah posisi Y
SUB PosX,32 ; Kembalikan posisi X mula-mula
POP CX ;
LOOP Ulang1 ; Test word pada baris berikutnya
SUB PosY,32 ; Kembalikan posisi Y mula-mula
POP DX ;
POP CX ; Ambil kembali semua nilai
POP BX ; register yang disimpan
POP AX ;
ENDM
;/=========================/;
.MODEL SMALL
.CODE
ORG 100h
TData : JMP Proses
Hall1 DW 0000000000000001b,1000000000000000b
DW 0000000000000011b,1000000000000000b
DW 0000000000000110b,0000000000000000b
DW 0000000000000111b,1000000000000000b
DW 0000000001111100b,1111110000000000b
DW 0000000110000100b,1000001100000000b
DW 0000001000001000b,0100000010000000b
DW 0000010000100000b,0011000001100000b
DW 0000100000100000b,0000100000010000b
DW 0001000000000000b,0000000000001000b
DW 0010000110000000b,0000000011000100b
DW 0100001111000000b,0000011111000100b
DW 0100000111100000b,0000011110000010b
DW 0100000110111000b,0001101100000010b
DW 0100000001111110b,0011111000000001b
DW 0100000000000000b,0000000000000001b
DW 0100000000000001b,1000000000000010b
DW 0100000000000011b,1100000000000010b
DW 0100000000000010b,1100000000000010b
DW 0010000100000000b,0000000010000010b
DW 0010000111000000b,0000001110000010b
DW 0010000011111100b,1100111100000100b
DW 0001000011111100b,1100111100000100b
DW 0001000001111111b,1111111000000100b
(186)
DW 0000100000011111b,1111100000001000b
DW 0000010000000111b,1110000000010000b
DW 0000001000000000b,0000000001100000b
DW 0000000110000000b,0000001110000000b
DW 0000000001110000b,1000010000000000b
DW 0000000000001111b,0111100000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
Hall2 DW 0000000000000011b,0000000000000000b
DW 0000000000000111b,0000000000000000b
DW 0000000000000110b,0000000000000000b
DW 0000000000000111b,1000000000000000b
DW 0000000001111100b,1111110000000000b
DW 0000000110000100b,1000001100000000b
DW 0000001000001000b,0100000010000000b
DW 0000010000100000b,0011000001100000b
DW 0000100000100000b,0000100000010000b
DW 0001000000000000b,0000000000001000b
DW 0010000100000000b,0000000010000100b
DW 0100001110000000b,0000011100000100b
DW 0100000111000000b,0000011100000010b
DW 0100000111100000b,0001111000000010b
DW 0100000001111000b,0011100000000001b
DW 0100000000000000b,0000000000000001b
DW 0100000000000001b,1000000000000010b
DW 0100000000000011b,1100000000000010b
DW 0100000000000010b,1100000000000010b
DW 0010000000000000b,0000000000000010b
DW 0010000000000000b,0000000000000010b
DW 0010000010000000b,0000000100000100b
DW 0001000011100000b,0000111100000100b
DW 0001000001111101b,1111111000000100b
DW 0000100000011111b,1111100000001000b
DW 0000010000000111b,1110000000010000b
DW 0000001000000000b,0000000001100000b
DW 0000000110000000b,0000001110000000b
DW 0000000001110000b,1000010000000000b
DW 0000000000001111b,0111100000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
Hall3 DW 0000000000111100b,0000000000000000b
DW 0000000000001111b,0000000000000000b
DW 0000000000000110b,0000000000000000b
DW 0000000000000111b,1000000000000000b
DW 0000000001111100b,1111110000000000b
DW 0000000110000100b,1000001100000000b
DW 0000001000001000b,0100000010000000b
DW 0000010000100000b,0011000001100000b
DW 0000100000100000b,0000100000010000b
DW 0001000000000000b,0000000000001000b
DW 0010000000000000b,0000000000000100b
DW 0100000000000000b,0000001100000100b
DW 0100000100000000b,0000011000000010b
DW 0100000111000000b,0000110000000010b
DW 0100000001111100b,0001100000000001b
DW 0100000000000000b,0000000000000001b
DW 0100000000000001b,1000000000000010b
DW 0100000000000011b,1100000000000010b
DW 0100000000000010b,1100000000000010b
DW 0010000000000000b,0000000000000010b
DW 0010000000000000b,0000000000000010b
DW 0010000011000000b,0000001000000100b
DW 0001000011111000b,0100111000000100b
DW 0001000000011100b,0111111000000100b
DW 0000100000001111b,1111100000001000b
DW 0000010000000000b,0000000000010000b
DW 0000001000000000b,0000000001100000b
DW 0000000110000000b,0000001110000000b
DW 0000000001110000b,1000010000000000b
DW 0000000000001111b,0111100000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
Hall4 DW 0000000001110000b,0000000000000000b
DW 0000000011011110b,0000000000000000b
DW 0000000000000111b,0000000000000000b
DW 0000000000000111b,1000000000000000b
DW 0000000001111100b,1111110000000000b
DW 0000000110000100b,1000001100000000b
DW 0000001000001000b,0100000010000000b
DW 0000010000100000b,0011000001100000b
DW 0000100000100000b,0000100000010000b
DW 0001000000000000b,0000000000001000b
DW 0010000000000000b,0000000000000100b
DW 0100000000000000b,0000000000000100b
DW 0100000000000000b,0000000000000010b
DW 0100000000000000b,0000000000000010b
DW 0100000000000000b,0000000000000001b
DW 0100000000000000b,0000000000000001b
DW 0100000000000001b,1000000000000010b
DW 0100000000000011b,1100000000000010b
DW 0100000000000010b,1100000000000010b
DW 0010000000000000b,0000000000000010b
DW 0010000000000000b,0000000000000010b
DW 0010000000000000b,0000000000000100b
DW 0001000000000000b,0000000000000100b
DW 0001000000000000b,0000000000000100b
DW 0000100000000000b,1000000000001000b
DW 0000010000000100b,0010000000010000b
DW 0000001000000011b,1100000001100000b
DW 0000000110000000b,0000001110000000b
DW 0000000001110000b,1000010000000000b
DW 0000000000001111b,0111100000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
PosX DW 150 ; Posisi awal X
PosY DW 70 ; Posisi awal Y
Proses:
SetCRT 13 ; Aktifkan mode video grafik
Hallo Hall1,20,0 ; gambar kode hall1 pada halaman 0
Hallo Hall2,21,1 ; gambar kode hall2 pada halaman 1
Hallo Hall3,22,2 ; gambar kode hall3 pada halaman 2
Hallo Hall4,23,3 ; gambar kode hall4 pada halaman 3
MOV AL,4
Ulang1:
DEC AL
Ak_Page AL ; Aktifkan halaman layar ke AL
Readkey
CMP AL,0
JNE Ulang1
Exit:
SetCRT 03h ; Kemabli ke mode video default dos
INT 20h
END TData
program 25.7. Animasi dengan halaman layar
Bila program 25.7. dieksekusi, maka pada layar akan ditampilkan gambar
pumpkin yang akan berubah mimik wajahnya setiap ditekan sembarang
tombol(gambar kode 25.6).
<<<<< Gbr257.PIX >>>>>
gambar kode 25.7. Hasil eksekusi program 25.7.
Pada awal program pelajar mangaktifkan modus grafik 13 yang memiliki
halaman tampilan sebanyak 4 buah(0, 1, 2 dan 3). sebab modus yang dipakai
memiliki halaman tampilan lebih dari satu, maka pada macro yang menggambar
Pixel, ditambahkan register BH yang berisi nomor halaman yang akan digambari
pixel.
halaman 2 b
Proses: :
CMP AX,1 ; Apakah error kode 1 ?
JNE Err2 ; Bukan! lompat ke Err2
Cetak Error1 ; Ya! Cetak pesan dari kode error 1
JMP Exit ; Keluar
Err2:
CMP AX,2 ; Apakah error kode 2 ?
JNE Err3 ; Bukan! lompat ke Err3
Cetak Error2 ; Ya! Cetak pesan dari kode error 2
JMP Exit ; Keluar
Err3:
CMP AX,3 ; Apakah error kode 3 ?
JNE Err4 ; Bukan! lompat ke Err4
Cetak Error3 ; Ya! Cetak pesan dari kode error 3
JMP Exit ; Keluar
Err4:
:
:
Apakah cara diatas sudah tepat ? Tidak!. Bila pengecekan dari kode
kesalahan hanyalah 1 atau 2 buah, cara diatas dapat kita pakai . Bagaimana
bila kode kesalahan yang akan pelajar cek, ternyata jumlahnya mencapai ratusan?
program kita akan tampak bertele-tele dan panjang selain itu ukuran file akan
menjadi sangat besar.
Salah satu cara yang dapat kita pakai untuk memecahkan masalah diatas
yaitu dengan membuat suatu tabel array yang berisi alamat offset dari masingmasing pesan kesalahan. lalu dari tabel alamat kode kesalahan ini
dipakai untuk mencetak pesan salah yang dihasilkan.
Cetak MACRO Kal
MOV AH,09
MOV DX,Kal
INT 21h
ENDM
;/====================/;
.MODEL SMALL
.CODE
ORG 100h
TData : JMP Proses
Error01 DB 'Salah perintah $'
Error02 DB 'File tidak ditemukan $'
Error03 DB 'Path tidak ditemukan $'
Error04 DB 'File yang dibuka terlalu banyak $'
Error05 DB 'Operasi ditolak $'
Error06 DB 'pemakaian file handle yang salah $'
Error07 DB 'MCB(Memory Control Blocks) sudah rusak $'
Error08 DB 'Kekurangan memory $'
Error09 DB 'Alamat memory blok salah $'
Error10 DB 'Environment String salah $'
Error11 DB 'Kesalahan format $'
Error12 DB 'Kode akses salah $'
Tabel DW Error01,Error02,Error03,Error04,Error05
DW Error06,Error07,Error08,Error09,Error10
DW Error11,Error12
Test_Error DW 03
Proses :
MOV AX,Test_Error
DEC AX
ADD AX,AX
MOV BX,AX
CETAK Tabel[BX] ; Cetak pesan kode error
INT 20h
END TData
program 23.4. Cara yang praktis untuk mencetak arti kode kesalahan DOS
Bila program 23.4. dijalankan, maka pada layar akan tercetak:
Path tidak ditemukan
Seperti yang diharapkan, arti kode error 03(Test_Error) akan tercetak
pada layar. kita bisa mengubah kode salah pada variabel Test_Error dengan
angka 01 sampai 12 untuk melihat pesan yang akan ditampilkan.
lihat :
Pada varibel Tabel pelajar mencatat alamat offet dari masing- masing pesan
kesalahan dengan cara:
Tabel DW Error01,Error02,Error03,Error04,Error05
DW Error06,Error07,Error08,Error09,Error10
DW Error11,Error12
yang mana masing-masing alamat offset memakai 1 word.
MOV AX,Test_Error
DEC AX
sebab kode error yang pertama yaitu 01, maka perlu pelajar kurangi dengan
1 agar menjadi 0. sehingga kode error 1 akan menunjuk pada word
pertama pada Tabel yang pelajar ketahui bahwa word pertama dari Tabel yaitu
alamat offset pesan kode salah 01.
ADD AX,AX
MOV BX,AX
sebab setiap alamat offset dari pesan kode salah memakai 1 word
atau 2 byte, maka untuk mengambil word selanjutnya dari Tabel yang mencatat
alamat offset pesan kode error selanjutnya, pelajar harus mengalikan kode error
dengan 2 atau menambah kode error dengan dirinya sendiri.
CETAK Tabel[BX]
lalu dengan Register Indirect Addressing pelajar mengambil alamat
offset pesan kode salah dari Tabel. Seperti biasa, pada pencetakan kalimat
pelajar mengambil alamat offset dari suatu string yang diakhiri dengan tanda '$'
untuk dicetak dengan fungsi 09 dari Dos. Pada pencetakan string ini alamat
offset sudah diperoleh dari Tabel[BX], sehingga perintah: "LEA DX,Kal" dari
fungsi 09 dapat dirubah menjadi: "MOV DX,Kal"
program RESIDEN
sudah dibahas mengenai pengertian dasar interupsi, bila kita
sudah lupa, bacalah kembali sebelum membaca bagian ini. Pada bagian ini akan
pelajar lihat lebih lanjut khusus mengenai vektor interupsi.
Seperti yang sudah dikatakan, setiap interupsi memakai 4 byte memory
sebagai alamat awal interupsi, yaitu alamat yang akan dituju setiap terjadi
interupsi. Keempat byte ini dicatat pada Interrupt Vektor Table yang ada
pada memory rendah, 0000:0000 sampai 0000:03FFh. sehingga , interupsi 00
memakai alamat 0000:0000-0000:0003, interupsi 01 memakai
alamat 0000:0004-0000:0007, dan seterusnya. Untuk mencari alamat awal dari
suatu nomor interupsi dipakai rumus:
Alamat Awal = 4 * Nomor-Interupsi
contoh : , setiap kali pelajar menekan tombol PrtScr untuk
mencetak isi layar pada printer akan selalu terjadi interupsi 05. Komputer
lalu akan menuju alamat awal interupsi 05, yaitu 0000:0020 (4*05=20). Dari
alamat awal ini lalu akan dilihat isi dari keempat byte, yaitu pada alamat
0000:0020 - 0000:0023. Keempat byte ini mencatat alamat CS(2 byte) dan IP(2
byte), yaitu alamat yang akan dituju oleh komputer selanjutnya. contoh isi
dari keempat byte ini yaitu 3200h:0D8Bh, artinya komputer akan melompat pada
alamat itu dan menjalankan program yang ada pada alamat itu
sampai bertemu dengan perintah IRET. program inilah yang dinamakan sebagai
Interrupt Handler 05, yaitu program yang akan dilakukan setiap kali terjadi
interupsi 05. Secara default program yang akan dilakukan ada pada
BIOS, yang mana program itu akan mencetak tampilan pada layar ke printer.
Untuk melihat isi dari alamat awal suatu vektor interupsi dapat
dipakai dua cara. Cara pertama, yaitu dengan membaca secara langsung
keempat byte alamat awal yang mencatat alamat berturut-turut Offset Lo, Offset
Hi, Segment Lo dan Segment Hi dari interrupt handler. Cara kedua yaitu dengan
memakai interupsi 21h fungsi 35h. Cara kedua lebih mudah untuk dipakai ,
oleh sebab itu akan pelajar pakai pada program -program selanjutnya.
Untuk memakai fungsi ke 35h ini, isilah AH dengan 35h dan AL dengan
nomor vektor interupsi sebelum dilakukan interupsi 21h. Hasil dari
interupsi ini akan disimpan pada pasangan register ES:BX. yang mana ES mencatat
alamat segment dan BX mencatat alamat offset vektor interupsi dari nomor
interupsi yang dimasukkan pada AL.
Ambil_Vec MACRO NoInt,Alamat
MOV AH,35h ; Servis untuk mencari vektor
MOV AL,NoInt ; No inteurpsi
INT 21h ; lakukan
MOV Alamat,BX ; Offset
MOV Alamat[2],ES ; Segment
ENDM
Untuk memakai macro ini kita bisa menyediakan suatu varibael 2 word
untuk menampung alamat hasil dari interupsi ini, seperti: Alamat DW ?,?.
Secara default, nomor interupsi 00h-7Fh akan menjalankan program yang
ada ROM BIOS, dan nomor interupsi 20h-FFh akan menjalankan program yang
disediakan oleh DOS. Interrupt Handler yang disediakan oleh BIOS ini tidak
bisa dihapus secara perangkat lunak dan selalu tersedia pada setiap komputer.
sedang Interrupt Handler yang disediakan oleh DOS akan tersedia pada saat
sistem operasi DOS sudah masuk kedalam memory komputer.
Suatu interrupt handler bisa saja diganti, contoh pelajar menginginkan
penekanan tombol PrtScr tidak mencetak isi layar namun mem-BOOT komputer sama
halnya dengan penekanan tombol Ctrl+Alt+Del. sebab Interrupt handler yang
asli, baik dari BIOS atau DOS tidak bisa dihapus maka cara yang dipakai
untuk merubah interrupt handler yaitu dengan mengganti isi dari Interrupt
Vektor Table.
Untuk mengganti atau mengarahkan suatu nomor interupsi dapat secara
langsung atau memakai fungsi 25h dari interupsi 21h. Untuk memakai
fungsi ini, isilah AH dengan 25h, AL dengan nomor interupsi yang akan diganti
vektornya, pasangan DS:DX berisi alamat yang akan dituju pada saat terjadi
interupsi itu .
Arah_Vec MACRO NoInt,Alamat
MOV AX,Alamat[2]
MOV DS,AX ; DS = segment
MOV DX,Alamat ; DX = offset
MOV AH,25h ; Servis untuk merubah vektor
MOV AL,NoInt ; No interupsi
INT 21h
ENDM
Sama seperti macro untuk memperoleh alamat vektor interupsi, untuk
memakai macro ini kita harus menyediakan suatu varibael 2 word yang
dipakai sebagai penampung alamat yang akan dituju dari suatu interupsi,
seperti: Alamat DW ?,?.
Pada program berikut ini akan kita lihat bagaimana membelokkan interupsi
05h(PrtScr) ke interupsi 1Bh. Interupsi 1Bh yaitu suatu interupsi yang akan
selalu terjadi bila kita menekan tombol Ctrl+Break. sehingga sesudah
program "breaks" dijalankan, penekanan tombol PrtScr akan seperti dengan
penekanan tombol Ctrl+Break.
Arah_Vec MACRO NoInt,Alamat
MOV AX,Alamat[2]
MOV DS,AX ; DS = segment
MOV DX,Alamat ; DX = offset
MOV AH,25h ; Servis untuk merubah vektor
MOV AL,NoInt ; No interupsi
INT 21h
ENDM
Ambil_Vec MACRO NoInt,Alamat
MOV AH,35h ; Servis untuk mencari vektor
MOV AL,NoInt ; No inteurpsi
INT 21h ; lakukan
MOV Alamat,BX ; Offset
MOV Alamat[2],ES ; Segment
ENDM
;/====================/;
.MODEL SMALL
.CODE
ORG 100h
TData : JMP Res_kan
Break EQU 23h
PrtScr EQU 05
Addr_Break DW ?,? ; Untuk menyimpan Alamat
; vektor Ctrl Break
Res_Kan :
Ambil_Vec Break,Addr_Break ; Anbil alamat Ctrl+C
Arah_Vec PrtScr,Addr_Break ; Rubah vektor PrtScr
INT 20h
END TData
program 24.1. Mengganti fungsi PrtScr menjadi Ctrl+Break
Bila progrm 24.1. dijalankan, maka tombol PrtScr sudah tidak akan
berfungsi seperti biasanya, namun berfungsi seperti penekanan tombol Ctrl
Break.
Pada waktu pelajar menyalakan komputer, ia mencari sistem operasi di drive
A: ataupun C: ,lalu memasukkannya kedalam memori bawah. Selanjutnya sistem
akan terus berada disitu dan apabila pelajar menjalankan program aplikasi
contoh game maka program itu akan disimpan di atas sistem operasi,
sehingga sistem operasi tetap ada walaupun pelajar sedang menjalankan game
itu . Inilah yang dinamakan residen, yaitu program yang tetap tinggal di
memori.
Dalam contoh pelajar ini bila game tadi sudah selesai maka ia akan lenyap
dari memori dan bila pelajar menjalankan program aplikasi lainnya, contoh WS
maka tempat memori yang dipakai oleh game pelajar akan dipakai oleh WS. Ini
yaitu contoh dari program yang tidak residen sebab ia hanya sementara waktu
berada di memori. Contoh program residen yang terkenal contoh SideKick,
Print(dos) dan Doskey.
+------------------+ +------------------+
| (USER AREA RAM) | | (USER AREA RAM) |
| | | |
| program | | program |
| APLIKASI 1 | | APLIKASI 2 |
| GAME | | WS |
+------------------+ +------------------+
| OPERATING SYSTEM | | OPERATING SYSTEM |
+------------------+ +------------------+
gambar kode 24.1. Peta RAM tanpa program Residen
program residen yaitu program yang akan menetap dimemory seperti halnya
DOS dan program residen ini akan berada tepat diatas Operating System. program
residen akan dianggap sebagai bagian dari Operating System sehingga bila
dijalankan program aplikasi maka program aplikasi itu akan ditaruh diatas
program residen sehingga program residen pelajar tetap utuh.
+------------------+ +------------------+
| (USER AREA RAM) | | (USER AREA RAM) |
| | | |
| program | | program |
| APLIKASI 1 | | APLIKASI 2 |
| GAME | | WS |
+------------------+ +------------------+
| RESIDENT SECTION | | RESIDENT SECTION |
+------------------+ +------------------+
| OPERATING SYSTEM | | OPERATING SYSTEM |
+------------------+ +------------------+
gambar kode 24.2. Peta RAM dengan program residen
program residen yaitu suatu bentuk program yang menarik. sebab program
residen menetap pada memory, maka semakin banyak program residen dijalankan,
memory akan semakin berkurang untuk dipakai oleh program aplikasi. program
residen, haruslah dibuat sekecil mungkin untuk menghindari pemakaian memory
yang terlalu banyak. Hanya dengan Assembler-lah, sebuah program dapat dibuat
sekecil mungkin! Bayangkan, program untuk menghapus layar, dengan bahasa
tingkat tinggi seperti pada pascal dan C dipakai sepelajar r 3232 byte,
sedang pada assembler sepelajar r 7 byte.
Dalam pembuatan program residen, pelajar dapat membaginya dalam 2 bagian
pokok, yaitu :
- Initialize section, yaitu bagian dari program yang bertugas meresidenkan
residen section. Bagian ini sendiri tidak residen, dan pada bagian inilah
suatu vektor interupsi diubah.
- Residen section, yaitu bagian program yang akan menetap pada memory. program
ini akan tetap tinggal pada memory sampai dihilangkan, atau sampai komputer
direset.
Pada program sebelumnya, pelajar selalu mengakhiri program dengan interupsi
20h yang akan mengembalikan kontrol program sepenuhnya pada DOS. Pada program
residen, program akan selalu pelajar akhiri dengan interupsi 27h ataupun
interupsi 21h fungsi 31h. Untuk memakai interupsi 27h, pelajar tinggal
mengisi pasangan register DS:DX dengan batas memory yang akan diresidenkan.
+------------------+
| |
| |
| USER AREA RAM |
| |
| |
+------------------+<--DS:DX
| RESIDENT SECTION |
+------------------+
| OPERATING SYSTEM |
+------------------+
gambar kode 24.3. pemakaian interupsi 27h untuk meresidenkan program
Untuk membuat program residen, kita bisa memakai bentuk program
seperti pada gambar kode 24.4.
----------------------------------------------------------------
.MODEL SMALL
.CODE
ORG 100h
TData : JMP Res_kan
+------------------+
| Tempat untuk |
| mengartikan |
| DATA |
+------------------+
Bag_Res PROC
PUSH AX ;
PUSH BX ;
PUSH CX ;
PUSH DX ;
PUSH ES ; Simpan isi semua register
PUSH DI ;
PUSH DS ;
(159)
PUSH SI ;
+------------------+
| Tempat handler |
| interupsi yang |
| baru |
+------------------+
POP SI ;
POP DS ;
POP DI ;
POP ES ;
POP DX ; Kembalikan isi semua register
POP CX ;
POP BX ;
POP AX ;
IRET ; Akhir dari interupt handler
Bag_Res ENDP
Res_Kan :
+------------------+
| Tempat untuk |
| memanipulasi |
| vektor interupsi |
+------------------+
LEA DX,Res_Kan
INT 27h
END TData
----------------------------------------------------------------
gambar kode 24.4. Model program Residen
24.6. program RESIDEN PERTAMA
Pada program berikut akan pelajar lihat bagaimana membelokkan merubah
vektor interupsi PrtScr menuju program pelajar . Dengan cara yang sama kita bisa
membelokkan vektor interupsi yang lain, dan membuat suatu handler yang baru
untuknya.
;/=======================/;
.MODEL SMALL
.CODE
ORG 100h
TData : JMP Res_kan
Pesan DB ' Interupsi 5<PrtScr> sudah di belokkan !! '
NoInt EQU 05h
Bag_Res PROC
PUSH AX ;
PUSH BX ;
PUSH CX ;
PUSH DX ;
PUSH ES ; Simpan isi semua register
PUSH DI ;
PUSH DS ;
PUSH SI ;
MOV AX,1300h ;
MOV BL,01001111b ;
MOV BH,00 ;
MOV DL,20 ;
MOV DH,12 ; program interupt handler PrtScr
MOV CX,44 ; yang baru.
PUSH CS ;
POP ES ;
LEA BP,Pesan ;
INT 10h ;
POP SI ;
POP DS ;
POP DI ;
POP ES ;
POP DX ; Kembalikan isi semua register
POP CX ;
POP BX ;
POP AX ;
IRET ; Akhir dari interupt handler
Bag_Res ENDP
Res_Kan :
MOV AH,25h ;
MOV AL,NoInt ; Untuk merubah vektor interupsi
LEA DX,Bag_Res ; 05 menuju 'Bag_Res'
INT 21h ;
LEA DX,Res_Kan ;
INT 27h ; Untuk meresidenkan bagian
END TData ; "Bag_Res"
program 24.2. Membuat program Residen
Bila program 24.2. dijalankan, maka tombol PrtScr sudah tidak akan
berfungsi lagi. Setiap kali tombol PrtScr ditekan, pada posisi 20,12 akan
ditampilkan pesan:
Interupsi 5<PrtScr> sudah di belokkan !!
lihat , bahwa pada program ini ada 2 bagian pokok, yaitu
bagian yang residen dan bagian yang meresidenkan. Bagian yang meresidenkan
hanya dijalankan sekali, sedang bagian yang residen akan dijalankan setiap
kali terjadi penekanan tombol PrtScr. Bagian yang meresidenkan yaitu:
Res_Kan :
MOV AH,25h ;
MOV AL,NoInt ; Untuk merubah vektor interupsi
LEA DX,Bag_Res ; 05 menuju 'Bag_Res'
INT 21h ;
LEA DX,Res_Kan ;
INT 27h ; Untuk meresidenkan bagian
END TData ; "Bag_Res"
Bagian ini tugasnya meresidenkan bagian Bag_Res. Sebelum bagian Bag_Res
diresidenkan, vektor interupsi PrtScr(05) diubah menuju progam Bag_Res. Bila
kita hanya merubah interupsi PrtScr menuju program Bag_Res tanpa diresidenkan,
maka akan memicu komputer kita menjadi hang, mengapa? Walaupun vektor
interupsi tetap menunjuk pada lokasi atau alamat yang sama, namun tempat yang
dipakai program pelajar sudah diserahkan kepada Dos untuk dipakai oleh
aplikasi lain.
Bag_Res PROC
PUSH AX ;
PUSH BX ;
PUSH CX ;
PUSH DX ;
PUSH ES ; Simpan isi semua register
PUSH DI ;
PUSH DS ;
PUSH SI ;
Ini yaitu awal dari bagian yang residen. Simpanlah semua nilai register
pada awal program residen untuk mencegah terganggunya program lain yang sedang
berjalan pada saat tombol PrtScr ditekan.
MOV AX,1300h ;
MOV BL,01001111b ;
MOV BH,00 ;
MOV DL,20 ;
MOV DH,12 ; program interupt handler PrtScr
MOV CX,44 ; yang baru.
PUSH CS ;
POP ES ;
LEA BP,Pesan ;
INT 10h ;
Bagian ini dapat dikatakan sebagai handler baru bagi interupsi PrtScr.
Tombol PrtScr yang biasanya mencetak tampilan layar pada printer akan berubah
menjadi mencetak pesan pada layar. sehingga kita bisa membuat handler
baru yang akan melakukan sesuatu setiap kali terjadi penekanan tombol PrtScr.
lihat ! :
untuk mencetak pesan pada layar dipakai interupsi 10h, dan bukannya
interupsi Dos fungsi 09 yang biasanya pelajar pakai . Mengapa demikian ?
Sebagian besar Interupsi Dos tidak bisa dipakai pada program residen, sebab
sifat dari Dos yang tidak reentrant. Masalah ini akan pelajar bicarakan lebih
lanjut nantinya.
POP SI ;
POP DS ;
POP DI ;
POP ES ;
POP DX ; Kembalikan isi semua register
POP CX ;
POP BX ;
POP AX ;
IRET ; Akhir dari interupt handler
Bag_Res ENDP
Pada akhir program residen, kembalikanlah nilai semua register yang
disimpan, ditambah perintah IRET(Interrupt Return). Perintah IRET akan
mengambil alamat CS dan IP dan nilai Flag pada stack untuk kembali menuju
program yang diselanya. CS, IP dan nilai flag disimpan pada stack pada saat
terjadi interupsi, inilah rahasianya mengapa program dapat berjalan normal
kembali sesudah memperoleh interupsi.
Pada alamat 40h:17h ada data tentang status tombol keyboard yang mana
bit ke 7 dipakai untuk mengartikan keadaan dari tombol caps lock. Bit
itu akan bernilai 1 bila caps lock sedang aktif dan 0 bila caps lock
tidak aktif. Dengan mengubah bit ke 7 pada alamat 40h:17h itu pelajar bisa
menyalakan tombol caps lock tanpa menekannya.
Aksi MACRO
MOV AX,40h
MOV ES,AX ; ES=40h
MOV AX,ES:[17h] ; AX=40h:17h
OR AX,01000000b ; Jadikan bit ke 7 menjadi 1
MOV ES:[17h],AX ; Masukkan kembali ke 40h:17h
ENDM
;/==================/;
.MODEL SMALL
.CODE
ORG 100h
TData : JMP Res_kan
NoInt EQU 1Ch
Bag_Res PROC
PUSH AX ;
PUSH BX ;
PUSH CX ;
PUSH DX ;
PUSH ES ; Simpan isi semua register
PUSH DI ;
PUSH DS ;
PUSH SI ;
Aksi
POP SI ;
POP DS ;
POP DI ;
POP ES ;
POP DX ; Kembalikan isi semua register
POP CX ;
POP BX ;
POP AX ;
IRET ; Akhir dari interupt handler
Bag_Res ENDP
Res_Kan :
MOV AH,25h ;
MOV AL,NoInt ; Untuk merubah vektor interupsi
LEA DX,Bag_Res ; 1Ch menuju 'Bag_Res'
INT 21h ;
LEA DX,Res_Kan ;
INT 27h ; Untuk meresidenkan bagian
END TData ; 'Bag_Res'
program 24.3. Mengunci Caps Lock
Pada program pelajar kali ini yang dibelokkan yaitu interupsi 1Ch. Handler
Interupsi ini secara defaultnya hanyalah berisi perintah IRET sebab interupsi
ini memang disediakan untuk dipakai oleh pemakai.
Interupsi 1Ch terjadi kurang lebih 18,2 kali setiap detiknya. sebab nya
dengan memakai interupsi 1Ch ini penekanan tombol Caps Lock menjadi
seakan-akan tidak berarti lagi sebab selalu dinyalakan oleh program pelajar .
Pada assembler ada suatu tipe data yang istimewa, yaitu
pendefinisian data melalui perintah LABEL, dengan syntax:
Nama LABEL TipeData
Pendefinisian data dengan DB, DW, DD, DF, DQ dan DT akan memicu
assembler menyediakan suatu tempat khusus. contoh kita mengartikan suatu
data dengan "A DW ?", maka assembler akan menyediakan 2 byte di memory
untuknya. kita hanya dapat memakai 2 byte pada memory melalui variabel
"A".
Dengan pemakaian label, assembler akan menyediakan memory dimulai dari
lokasi pendefinisiannya sampai sebatas memory kita . Selain itu pemakaian
Label tidak memakai memory khusus. Pada program 24.4, program COM yang
dihasilkan memakai memory 26 byte. Bila pemakaian label dihilangkan dan
pengisian angka untuk variabel A,B dan C dilakukan secara langsung, memory
yang dipakai oleh pada program 24.4. juga 26 byte!.
;/===================/;
.MODEL SMALL
.CODE
ORG 100h
TData : JMP Proses
XX LABEL BYTE
A DB 1
B DB 2
C DB 3
Proses:
MOV XX[0],0Ah ; = MOV A,0Ah
MOV XX[1],0Bh ; = MOV B,0Bh
MOV XX[2],0Ch ; = MOV C,0Bh
(163)
INT 20h
END TData
program 24.4. pemakaian LABEL
sebab pelajar mengartikan "XX label byte" diatas variabel A, maka byte
pertama dari "XX" akan sama dengan variabel "A", byte keduanya sama dengan "B"
dan byte ketiganya sama dengan "C". sehingga perintah "MOV XX[0],0Ah"
yaitu identik dengan "MOV A,0Ah".
+-XX+---+---+---+---
+---+---+---+---+---
| 1 | 2 | 3 | |
+---+---+---+---+---
"A" "B" "C"
Dengan pemakaian label ini, pelajar bisa mengakses suatu tempat di memory
dengan memakai 2 atau lebih nama yang berlainan. Apa kelebihan lainnya ?
- Dengan mengartikan suatu variabel label pada akhir program , maka akan
diperoleh suatu variabel penampung yang besar sekali, tanpa harus
memperbesar program .
- Dengan pendefinisian label juga dimungkinkan pengaksesan data dengan tipe
data yang berlainan pada variabel. agar lebih jelas, bisa kita lihat pada
program berikut ini:
;/=================/;
.MODEL SMALL
.CODE
ORG 100h
TData : JMP Proses
XX LABEL WORD
A DB 1,2
Proses:
MOV XX,0Ah ;=> A[0]=0Ah Dan A[1]=00
INT 20h
END TData
program 24.5. Merubah tipe data dengan Label
Pada program 24.5. dapat dilihat bahwa pelajar bisa saja mengakses nilai
pada variabel A yang didiartikan dengan tipe data byte diakses dengan tipe
data word. sehingga pemakaian label memungkinkan pelajar untuk mengakses
suatu data dengan tipe data yang berbeda.
+--XX---+-------+---
+---+---+---+---+---
| 1 | 2 | | |
+---+---+---+---+---
A[0] A[1]
24.9. MEMANGGIL HANDLER INTERUPSI LAMA
Pada program yang mengganti handler interupsi, kadang-kadang pelajar masih
ingin melakukan handler yang asli. Untuk itu lihatlah pada program 24.6.
berikut:
Cetak_Pesan MACRO Pesan,Banyak,X,Y
MOV AX,1300h ; Fungsi untuk mencetak kalimat
MOV BL,01001111b ; Atribut
MOV BH,00 ; Nomor halaman
MOV DL,X ; Posisi kolom
MOV DH,Y ; Posisi baris
MOV CX,Banyak ; Banyaknya huruf
PUSH CS ; ES:BP mencatat +
POP ES ; lokasi kalimat
LEA BP,Pesan ;
INT 10h ; lakukan
ENDM
Readkey MACRO ; Macro untuk menunggu penekanan
MOV AH,00 ; sembarang tombol dari keyboard
INT 16h ;
ENDM
Ambil_Vec MACRO NoInt,Alamat
MOV AH,35h ; Servis untuk mencari vektor
MOV AL,NoInt ; No interupsi
INT 21h ; lakukan
MOV Alamat,BX ; Offset
MOV Alamat[2],ES ; Segment
ENDM
;/==========================/;
.MODEL SMALL
.CODE
ORG 100h
TData : JMP Res_kan
PrtScr EQU 05
Addr_PrtScr_Asli LABEL DWORD
Addr_PrtScr DW ?,?
Pesan1 DB '--> Siapkan printer kita !! Tekan'
DB ' sembarang tombol untuk mulai'
DB ' mencetak <--'
Pesan2 DB '>> PrtScr sudah dilakukan ,'
DB 'semoga kita puas dengan hasilnya <<'
Bag_Res PROC
PUSH AX ;
PUSH BX ;
PUSH CX ;
PUSH DX ;
PUSH ES ; Simpan isi semua register
PUSH DI ;
PUSH DS ;
PUSH SI ;
Cetak_Pesan Pesan1,80,0,12
Readkey
PUSHF
CALL Addr_PrtScr_Asli ; Panggil handler PrtScr
; yang asli
Cetak_Pesan Pesan2,65,5,14
POP SI ;
POP DS ;
POP DI ;
POP ES ;
POP DX ; Kembalikan isi semua register
POP CX ;
POP BX ;
POP AX ;
IRET ; Akhir dari interupt handler
Bag_Res ENDP
Res_Kan :
Ambil_Vec PrtScr,Addr_PrtScr
MOV AH,25h ;
MOV AL,PrtScr ; Membelokkan vektor interupsi
LEA DX,Bag_Res ;
INT 21h ;
LEA DX,Res_Kan ; Meresidenkan program Bag_Res
INT 27h
END TData
program 24.6. Teknik memanggil handler interupsi yang asli
Bila program 24.6. dijalankan, maka setiap penekanan tombol PrtScr,
komputer akan menampilkan pesan:
---> Siapkan printer kita !!
Tekan sembarang tombol untuk mulai mencetak <---
Komputer akan segera mencetak isi layar pada printer bila ditekan
sembarang tombol. Pencetakan dilakukan dengan memanggil interrupt handler
PrtScr yang asli dengan:
PUSHF
CALL Addr_PrtScr_Asli
Kedua perintah ini mensimulasikan perintah interrupt. Seperti yang sudah
pelajar ketahui, setiap interrupt handler selalu diakhiri dengan perintah IRET
yang akan mengambil CS, IP dan Flags dari stack. sebab perintah Call hanya
akan menyimpan CS dan IP dalam stack maka pelajar perlu menyimpan flags dalam
stack secara manual. Pada variabel "Addr_PrtScr_Asli" pelajar mengartikan nya
sebagai label Double Word sehingga kedua word variabel "Addr_PrtScr" dapat
diakses dengan tipe data Double Word(alamat CS dan IP).
Pada saat pertama DOS diciptakan, ia dirancang dengan system single
user, sehingga DOS sering dinamakan "non-reentrant operating system".
Bila terjadi interupsi dari DOS sementara interupsi DOS yang lainnya sedang
aktif, data-data yang tersimpan dalam stack akan menjadi berantakan dan
komputer akan menjadi hang. Inilah sebabnya, mengapa pada program residen
interupsi dari DOS tidak bisa dipakai . namun DOS menyediakan banyak fungsi
yang sangat berguna dan tidak ada pada fungsi BIOS, seperti penanganan
operasi pada file, memory dan sebagainya. Banyak pelajar yang mengira bahwa
interupsi DOS tidak boleh sama sekali dipakai dalam program residen. Benarkah
demikian ? Tidak.
,, interupsi DOS tidak boleh terjadi
bersamaan, sehingga untuk memakai fungsi DOS pada program residen yang
perlu pelajar lakukan yaitu " Jangan memakai fungsi DOS bila fungsi DOS yang
lain sedang aktif ". Bagaimana pelajar bisa mengetahui bahwa suatu fungsi DOS
sedang aktif atau tidak ? Untuk itu kita bisa memakai kedua cara berikut:
1. pakai fungsi 34h dari interupsi 21h untuk memperoleh InDOS Flag atau
Bendera Aktif DOS(BAD). Untuk memakai fungsi ini, masukkan 34h pada
AH, lalu lakukan interupsi 21h. Sesudah interupsi dilakukan ,
pasangan register ES:BX akan mencatat alamat tempat BAD berada. BAD yang
terdiri atas 1 byte akan bernilai nol(0) bila fungsi DOS tidak ada yang
sedang aktif. Artinya pada keadaan ini pelajar bisa memakai fungsi DOS
pada program residen dengan aman. Bila BAD bernilai lebih dari 0, artinya
ada fungsi DOS yang sedang aktif. Dalam keadaan seperti ini pelajar
tidak boleh memakai fungsi DOS pada program residen, sebab akan
meyebabkan komputer menjadi hang.
2. DOS mungkin saja dalam keadaan aman, walaupun BAD bernilai lebih dari
0(biasanya 1). Untuk mengartikan keadaan aman ini DOS akan selalu
mengaktifkan interupsi 28h. Handler asli dari interupsi 28h ini hanyalah
berupa perintah IRET. Bila interupsi 28h ini diaktifkan, pelajar bisa
memakai fungsi DOS dengan aman pada program residen. Interupsi 28h ini
biasanya diaktifkan DOS pada saat DOS sedang menunggu masukan dari
keyboard dengan fungsi 01h-0Ch. Untuk memakai interupsi ini, buatlah
suatu handler baru untuknya.
Pada program 24.7. akan ditunjukkan bagaimana interupsi dari DOS, yaitu
interupsi 21h fungsi 09h dipakai pada program residen. Dengan teknik yang
sama, kita bisa memakai segala fungsi dari interupsi DOS dalam program
residen tanpa perlu takut program kita menjadi hang.
Cetak_Pesan MACRO Pesan ; Mencetak kalimat dengan
MOV AH,09 ; interupsi dari DOS
PUSH CS ;
POP DS ; Samakan nilai CS dan DS
LEA DX,Pesan ;
INT 21h ; Interupsi DOS
ENDM
Ambil_Vec MACRO NoInt,Alamat
MOV AH,35h ; Servis untuk mencari vektor
MOV AL,NoInt ; No interupsi
INT 21h ; lakukan
MOV Alamat,BX ; Offset
MOV Alamat[2],ES ; Segment
ENDM
;/============/;
.MODEL SMALL
.CODE
ORG 100h
TData : JMP Res_kan
PrtScr EQU 05
Addr_PrtScr_Asli LABEL DWORD
Addr_PrtScr DW ?,?
Pesan DB ' Kalimat ini dicetak dengan fungsi'
DB ' dari DOS. ',13,10
DB ' Pemecahan masalah '
DB 'Reentrancy DOS !!!$'
Offset_BAD DW ?
Segmen_BAD DW ?
Res05 PROC
PUSH AX ;
PUSH BX ;
PUSH CX ;
PUSH DX ;
PUSH ES ; Simpan isi semua register
PUSH DI ;
PUSH DS ;
PUSH SI ;
MOV AX,Segmen_BAD
MOV ES,AX
MOV BX,Offset_BAD ; ES:BX = alamat BAD
CMP BYTE PTR ES:[BX],0 ; Apakah ada fungsi DOS yang
; sedang aktif?
JNE Pulihkan ; Ya, jangan lakukan
Aman : ; interupsi DOS
Cetak_Pesan Pesan ; Tidak, lakukan interupsi DOS
Pulihkan:
POP SI ;
POP DS ;
POP DI ;
POP ES ;
POP DX ; Kembalikan isi semua register
POP CX ;
POP BX ;
POP AX ;
IRET ; Akhir dari interupt handler
Res05 ENDP
Res_Kan :
Ambil_Vec PrtScr,Addr_PrtScr
MOV AH,25h ;
MOV AL,PrtScr ; Membelokkan vektor interupsi
LEA DX,Res05 ;
INT 21h ;
MOV AH,34h ;
INT 21h ; Ambil alamat InDOS flag
MOV Segmen_BAD,ES ; atau BAD
MOV Offset_BAD,BX ;
LEA DX,Res_Kan ; Meresidenkan program Bag_Res
INT 27h
END TData
program 24.7. memakai fungsi DOS dalam program Residen
Bila program 24.7. dijalankan, maka setiap kali terjadi penekanan
pada tombol PrtScr, program akan melihat keadaan aman atau tidak untuk
memakai interupsi DOS. Bila BAD bernilai nol atau keadaan aman, program
akan mencetak kalimat dengan fungsi dari DOS. Pesan yang tercetak yaitu:
Kalimat ini dicetak dengan fungsi dari DOS.
Pemecahan masalah Reentrancy DOS !!!
Bila BAD bernilai lebih dari nol atau keadaan tidak aman, program tidak
memakai fungsi dari DOS dan akan segera keluar.
Pada modus text, layar dibagi menjadi kotak-kotak yang membentuk
huruf . Pada modus default Dos, layar terbagi menjadi 80 kotak horisontal
dan 25 kotak vertical. pelajar bisa saja membentuk suatu gambar kode pada modus teks,
akan namun hasilnya tentu saja sangat kasar.
Pada modus grafik, layar dibagi menjadi titik-titik yang dinamakan sebagai
Pixel. Untuk memrogram pada modus grafik ini, tentunya kita harus mengaktifkan
mode layar grafik terlebih dahulu (Lihat 18.10 tentang mode layar). contoh
kita mengaktifkan mode 13h, maka layar akan dibagi menjadi 320 X 200 pixel,
atau sama dengan 64000 titik. Bila diaktifkan mode 06h, maka layar akan dibagi
menjadi 640 X 200 pixel atau sama 128000 pixel. Tentunya pada mode 06 ini
gambar kode akan tampak lebih halus. kita harus ingat bahwa tidak semua mode
didukung oleh monitor kita . kita harus mengetahui dengan jelas jenis monitor
dan modus apa saja yang didukungnya.
Bila kita memakai komputer, seperti Hercules dan Macintosh maka
dengan mudah kita dapat menggambar kode lingkaran, garis, dan mewarnai gambar
itu . Bagaimana pada komputer IBM PC dan kompatiblenya?
Pada komputer IBM PC dan kompatiblenya, kemampuan menggambar kode pada modus
grafik hanyalah satu, yaitu menggambar kode pixel(titik). Kemampuan ini tampaknya
sangatlah kurang, namun pada bagian ini akan pelajar lihat bagaimana memakai
fasilitas ini untuk menggambar kode berbagai gambar kode yang menarik.
Untuk menggambar kode pixel ini aktifkanlah modus grafik terlebih dahulu.
Sesudah itu kita bisa menggambar kode pixel dengan fungsi 0Ch, dengan aturan
pemakaian:
INPUT:
AH = 0Ch
AL = Atribut dari pixel. bila bit ke 7-nya 1, maka pixel akan
di Xor dengan gambar kode layar.
CX = Posisi kolom(X) tempat pixel akan digambar kode
DX = Posisi baris(Y) tempat pixel akan digambar kode
BH = Nomor halaman, bila modus video yang dipakai memiliki
halaman tampilan melebihi satu. bila modus yang dipakai
hanya memakai 1 halaman tampilan, maka isi BH akan
diabaikan.
Sesudah semuanya kita persiapkan, lakukan lah interupsi 10h. Contoh
dari macro untuk menggambar kode pixel:
Pixel MACRO X,Y,Warna
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV AH,0Ch
MOV CX,X ; Posisi kolom atau X
MOV DX,Y ; Posisi baris atau Y
MOV AL,Warna ; Atribut Pixel
INT 10h ; gambar kode pixel itu !
POP DX
POP CX
POP BX
POP AX
ENDM
Kebalikan dari fungsi 0Ch, fungsi 0Dh dari interupsi 10h dipakai untuk
memperoleh warna dari suatu pixel. Aturan untuk memakai fungsi ini
yaitu:
INPUT:
AH = 0Dh
CX = Posisi kolom(X) dari pixel
DX = Posisi baris(Y) dari pixel
BH = Nomor halaman, bila modus video yang dipakai memiliki
halaman tampilan melebihi satu. bila modus yang dipakai
hanya memakai 1 halaman tampilan, maka isi BH akan
diabaikan.
OUTPUT:
AL = Atribut dari pixel pada kolom CX dan baris DX.
Bila suatu benda dibagi-bagi terus, maka akan kita dapatkan apa yang
dinamakan sebagai atom, atau bagian terkecil dari suatu benda. Demikian halnya
pada gambar, bila dilihat secara seksama, setiap gambar kode terbentuk atas titiktitik. Makin banyak titik yang membentuk suatu gambar, makin haluslah gambar kode
itu . Dengan prinsip yang sama, pelajar bisa membuat bermacam gambar kode yang
menarik.
- Untuk menggambar kode garis vertical atau horisontal yaitu cukup mudah. kita
hanya perlu menggambar kode titik-titik secara berurutan untuk menghasilkan sebuah
garis.
- Untuk menggambar kode garis Vertical ke bawah, kita hanya perlu menambah posisi
baris(Y) dengan posisi kolom(X) yang tetap. sedang untuk menggambar kode garis
Horisontal ke kanan, kita hanya perlu menambah posisi kolom(X) dengan posisi
baris(Y) yang tetap(Lihat program 25.1).
Readkey MACRO
MOV AH,00
INT 16h
ENDM
SetCRT MACRO Mode
MOV AH,00
MOV AL,Mode
INT 10h
ENDM
PutPixel MACRO X,Y,Warna
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV AH,0C ; Servis menggambar kode pixel
MOV CX,X ; Posisi kolom atau X
MOV DX,Y ; Posisi baris atau Y
MOV AL,Warna ; Atribut Pixel
INT 10h ; gambar kode pixel itu !
POP DX
POP CX
POP BX
POP AX
ENDM
GarisV MACRO X1,Y1,Panjang,Warna
LOCAL Ulang
PUSH DX
PUSH CX
MOV DX,Y1
MOV CX,Panjang
Ulang:
PutPixel X1,DX,Warna
INC DX
LOOP Ulang
POP CX
POP DX
ENDM
GarisH MACRO X1,Y1,Panjang,Warna
LOCAL Ulang
PUSH CX
PUSH DX
MOV DX,X1
MOV CX,Panjang
Ulang:
PutPixel DX,Y1,Warna
INC DX
LOOP Ulang
POP DX
POP CX
ENDM
;/===========/;
.MODEL SMALL
.CODE
ORG 100h
Proses:
SetCRT 13h ; Aktifkan mode grafik 13h
GarisV 150,50,50,12 ; gambar kode garis Vertikal
Readkey ; Tunggu penekanan keyboard
GarisH 135,60,30,12 ; gambar kode garis Horisontal
Readkey ; Tunggu penekanan keyboard
SetCRT 03h ; Kembali pada mode Dos
INT 20h
END Proses
program 25.1. Menggambar kode garis Vertical dan Horisontal
Bila program 25.1. dieksekusi, maka pada layar akan ditampilkan sebuah
gambar kode salib yang terdiri atas garis vertical dan horisontal.
<<<< Gbr251.PIX >>>>
gambar kode 25.1. Hasil eksekusi program 25.1.
Untuk menggambar kode sebuah garis miring, prinsip yang dipakai tidak
jauh berbeda dengan menggambar kode garis lurus. Untuk menggambar kode sebuah garis
miring 45 derajat ke kiri bawah, kita hanya perlu menggambar kode pixel sambil
mengurangi posisi kolom(X) dan menambah posisi baris(Y). sedang untuk
menggambar kode sebuah garis miring 45 derajat ke kanan bawah, kita bisa menggambar kode
pixel sambil menambahi posisi kolom(X) dan menambah posisi baris(Y).
Readkey MACRO
MOV AH,00
INT 16h
ENDM
SetCRT MACRO Mode
MOV AH,00
MOV AL,Mode
INT 10h
ENDM
PutPixel MACRO X,Y,Warna
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV AH,12 ; Servis menggambar kode pixel
MOV CX,X ; Posisi kolom atau X
MOV DX,Y ; Posisi baris atau Y
MOV AL,Warna ; Atribut Pixel
INT 10h ; gambar kode pixel itu !
POP DX
POP CX
POP BX
POP AX
ENDM
M_Kanan MACRO X1,Y1,Panjang,Warna
LOCAL Ulang
PUSH BX
PUSH CX
PUSH DX
MOV DX,X1
MOV BX,Y1
MOV CX,Panjang
Ulang:
PutPixel DX,BX,Warna
INC DX
INC BX
LOOP Ulang
POP DX
POP CX
POP BX
ENDM
M_Kiri MACRO X1,Y1,Panjang,Warna
LOCAL Ulang
PUSH BX
PUSH CX
PUSH DX
MOV DX,X1
MOV BX,Y1
MOV CX,Panjang
Ulang:
PutPixel DX,BX,Warna
DEC DX
INC BX
LOOP Ulang
POP DX
POP CX
POP BX
ENDM
;/=========================/;
.MODEL SMALL
.CODE
ORG 100h
Proses:
SetCRT 13h
M_Kiri 150,0,50,83 ; Garis miring kiri
Readkey
M_Kanan 150,0,50,83 ; Garis miring kanan
Readkey
SetCRT 03h
INT 20h
END Proses
program 25.2. Menggambar kode garis miring
Bila program 25.2. dieksekusi, maka pada layar akan ditampilkan sebuah
gambar kode atap rumah yang terdiri atas garis miring kekanan dan kiri.
<<<< Gbr252.PIX >>>>
gambar kode 25.2. Hasil eksekusi program 25.2.
25.6. MENGgambar kode KOTAK
Sebuah kotak terdiri atas 2 garis vertical dan 2 garis horisontal. Untuk
itu kita bisa memakai macro dari GarisV dan GarisH untuk menggambar kode kotak
ini. pelajar hanya menentukan posisi
X1,Y1 dan X2,Y2(gambar kode 25.3) untuk menggambar kode sebuah kotak. Perhatikan, bahwa
X2 > X1 dan Y2 > Y1.
X1,Y1+-----------------------+X2,Y1
| X2-X1 |
| |
| |
|Y2-Y1 Y2-Y1|
(175)
| |
| |
| X2-X1 |
X1,Y2+-----------------------+X2,Y2
gambar kode 25.3. Teknik menggambar kode kotak
Dari gambar kode 25.3. dapat kita lihat, dengan mudah sebuah kotak dapat
digambar kode dengan bantuan macro untuk menggambar kode garis vertikal dan horisontal.
Readkey MACRO
MOV AH,00
INT 16h
ENDM
SetCRT MACRO Mode
MOV AH,00
MOV AL,Mode
INT 10h
ENDM
PutPixel MACRO X,Y,Warna
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV AH,0C ; Servis menggambar kode pixel
MOV CX,X ; Posisi kolom atau X
MOV DX,Y ; Posisi baris atau Y
MOV AL,Warna ; Atribut Pixel
INT 10h ; gambar kode pixel itu !
POP DX
POP CX
POP BX
POP AX
ENDM
GarisV MACRO X1,Y1,Panjang,Warna
LOCAL Ulang
PUSH DX
PUSH CX
MOV DX,Y1
MOV CX,Panjang
Ulang:
PutPixel X1,DX,Warna
INC DX
LOOP Ulang
POP CX
POP DX
ENDM
GarisH MACRO X1,Y1,Panjang,Warna
LOCAL Ulang
PUSH CX
PUSH DX
MOV DX,X1
MOV CX,Panjang
Ulang:
PutPixel DX,Y1,Warna
INC DX
LOOP Ulang
POP DX
POP CX
ENDM
Kotak MACRO X1,Y1,X2,Y2,Warna
GarisH X1,Y1,X2-X1,Warna
GarisV X1,Y1,Y2-Y1,Warna
GarisV X2,Y1,Y2-Y1,Warna
GarisH X1,Y2,X2-X1+1,Warna
ENDM
;/================/;
.MODEL SMALL
.CODE
ORG 100h
Proses:
SetCRT 13h
Kotak 120,30,180,100,12 ; gambar kode kotak
Readkey
SetCRT 03h
INT 20h
END Proses
program 25.3. Menggambar kode Kotak
Bila program 25.3. dieksekusi, maka pada layar akan ditampilkan sebuah
gambar kode kotak persegi empat(gambar kode 25.4).
<<<< Gbr254.PIX >>>>
gambar kode 25.4. Hasil eksekusi program 25.3.
Pada program 25.3., pelajar hanya sekedar menggambar kode sebuah kotak tanpa
warna dasar. Untuk memberi warna pada kotak pelajar harus menggambar kode pixel-pixel
pada seluruh area kotak yang kosong. sehingga kotak akan menjadi
berwarna.
Untuk menggambar kode area kotak ini, bisa kita pakai bermacam-maca cara,
contoh dengan menggambarkan garis vertical ataupun garis horisontal. Pada
program 25.4. pelajar akan mewarnai area yang kosong pada kotak dengan dengan
garis-garis Horisontal.
Readkey MACRO
MOV AH,00
INT 16h
ENDM
SetCRT MACRO Mode
MOV AH,00
MOV AL,Mode
INT 10h
ENDM
PutPixel MACRO X,Y,Warna
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV AH,12 ; Servis menggambar kode pixel
MOV CX,X ; Posisi kolom atau X
MOV DX,Y ; Posisi baris atau Y
MOV AL,Warna ; Atribut Pixel
INT 10h ; gambar kode pixel itu !
POP DX
POP CX
POP BX
POP AX
ENDM
GarisV MACRO X1,Y1,Panjang,Warna
LOCAL Ulang
PUSH DX
PUSH CX
MOV DX,Y1
MOV CX,Panjang
Ulang:
PutPixel X1,DX,Warna
INC DX
LOOP Ulang
POP CX
POP DX
ENDM
GarisH MACRO X1,Y1,Panjang,Warna
LOCAL Ulang
PUSH CX
PUSH DX
MOV DX,X1
MOV CX,Panjang
Ulang:
PutPixel DX,Y1,Warna
INC DX
LOOP Ulang
POP DX
POP CX
ENDM
Kotak MACRO X1,Y1,X2,Y2,Warna
GarisH X1,Y1,X2-X1,Warna
GarisV X1,Y1,Y2-Y1,Warna
GarisV X2,Y1,Y2-Y1,Warna
GarisH X1,Y2,X2-X1+1,Warna
ENDM
KotakW MACRO X1,Y1,X2,Y2,Warna
LOCAL Ulang1,Ulang2
PUSH AX
PUSH CX
MOV AX,Y1+1
MOV CX,Y2-Y1-1
Ulang1:
GarisH X1+1,AX,X2-X1-1,Warna
INC AX
LOOP Ulang1
POP CX
POP AX
ENDM
;/===================/;
.MODEL SMALL
.CODE
ORG 100h
Proses:
SetCRT 13h
Kotak 120,30,180,100,12 ; gambar kode kotak
Readkey
KotakW 120,30,180,100,09 ; Warnai kotak
Readkey
SetCRT 03h
INT 20h
END Proses
program 25.4. Mewarnai Kotak
Bila program 25.4. dieksekusi, maka pada layar akan ditampilkan sebuah
gambar kode kotak yang sudah diwarnai (gambar kode 25.5).
<<<<< Gbr255.PIX >>>>>
gambar kode 25.5. Hasil eksekusi program 25.4.
Pada program 25.4. ini, kotak akan diwarnai seluruhnya. Cobalah kita
membuat kreasi sendiri, contoh kotak akan diwarnai dengan garis-garis
vertical, garis-garis harisontal atau kotak- kotak kecil.
Pada program sebelumnya, pelajar selalu menggambar kode bentuk gambar kode yang
linear. Kini, bila kita ingin menggambar kode sebuah gambar kode tak tentu, seperti
manusia, tengkorak, tank, bunga atau helikopter, dengan rumus yaitu tidak
mungkin.
Untuk itu salah satu cara yang praktis yaitu membentuk suatu tabel
gambar. Dari tabel ini lalu kita lihat secara perBITnya. Bila bit pada
data gambar kode bernilai satu, maka gambarlah sebuah pixel, sebaliknya bila Bit
pada data gambar kode bernilai nol maka pixel tidak digambar. Sesudah itu
pindahkan posisi X(Kolom) dan test bit berikutnya.
Dengan cara demikian kita bisa membuat gambar kode dalam ukuran yang
berapapun, sesuai resolusi monitor kita . Pada program 25.5. akan ditunjukkan,
bagaimana membuat sebuah gambar kode helikopter dengan ukuran 32 bit X 32 bit.
Readkey MACRO ; Untuk menunggu masukan dari
MOV AH,00 ; Keyboard
INT 16h
ENDM
SetCRT MACRO Mode ; Untuk merubah mode layar
MOV AH,00 ;
MOV AL,Mode ;
INT 10h
ENDM
Pixel MACRO X,Y,Warna ; Untuk menggambar kode pixel
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV AH,12 ; Servis menggambar kode pixel
MOV CX,X ; Posisi kolom atau X
MOV DX,Y ; Posisi baris atau Y
MOV AL,Warna ; Atribut Pixel
INT 10h ; gambar kode pixel itu !
POP DX
POP CX
POP BX
POP AX
ENDM
;/====================/;
.MODEL SMALL
.CODE
ORG 100h
TData : JMP Proses
gambar kode DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000001110000000b
DW 0000000000000000b,0000000100000000b
DW 0000000011111111b,1111111111111110b
DW 0000000000000000b,0000000100000000b
DW 0000000000000000b,0111111111000000b
DW 1110000000000000b,1111111111100000b
DW 0100000000111111b,1111000100110000b
DW 0111111111111111b,1111000100011000b
DW 0000000000000011b,1111000111111000b
DW 0000000000000000b,0111111111100000b
DW 0000000000000000b,0010000100001000b
DW 0000000000111111b,1111111111110000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
PosX DW 100 ; Posisi awal X
PosY DW 30 ; Posisi awal Y
Proses:
SetCRT 13h ; Aktifkan mode grafik
SUB BX,BX ;
MOV CX,32 ; CX=banyaknya baris
Ulang1:
PUSH CX
MOV CX,2 ; CX=banyaknya Word dalam 1 baris
Ulang2:
PUSH CX
MOV CX,16 ; CX=Banyaknya bit dalam 1 word
MOV AX,1000000000000000b
Ulang3:
PUSH AX
AND AX,Gambar[BX] ; Test bit gambar kode yang ke AX
JZ Nol ; bila nol, lompat
Pixel PosX,PosY,83 ; bila tidak, gambar kode pixel
Nol:
POP AX ;
SHR AX,1 ;
INC PosX ; Tambah posisi X
LOOP Ulang3 ; Test bit gambar kode berikutnya
ADD BX,2 ; Akses word berikutnya
POP CX
LOOP Ulang2 ; Test word berikutnya
INC PosY ;
SUB PosX,32 ; Kembalikan posisi X mula-mula
POP CX
LOOP Ulang1 ; Test word pada baris berikutnya
Exit:
Readkey
SetCRT 03h ; Aktifkan Mode default Dos
(181)
INT 20h
END TData
program 25.5. Menggambar kode Helikopter
Bila program 25.5. dieksekusi, maka pada layar akan ditampilkan sebuah
gambar kode helikopter (gambar kode 25.6). Helikopter ini digambar kode berdasar data
gambar kode pada variabel "Gambar".
<<<<< Gbr256.PIX >>>>>
gambar kode 25.6. Hasil eksekusi program 25.5.
Catatan:
Dengan teknik yang tidak jauh berbeda, kita bisa membuat program yang
dapat menampilkan bermacam format gambar, seperti GIF, PIX, BMP, dan
sebagainya.
Pada grafik, yang paling menarik yaitu membuat sebuah animasi. Seperti
dinosaurus yang sedang berjalan, bunga yang sedang berkembang, pesawat yang
meledak dan sebagainya. Dibalik pembuatan animasi ini ada berpuluh-puluh
cara yang dapat dipakai .
Salah satu cara yang paling praktis dan mudah, walaupun tidak begitu
bagus yaitu dengan teknik gambar kode hapus. Yaitu animasi dengan cara menggambar kode
sebuah gambar, lalu dihapus dan digambar kode lagi pada posisi atau bentuk
gambar kode yang berbeda. Dengan cara ini sebuah gambar kode akan tampak seperti sedang
bergerak (program 25.6).
Delay MACRO
LOCAL Ulang
PUSH CX
SUB CX,CX
Ulang:
LOOP Ulang
POP CX
ENDM
SetCRT MACRO Mode
MOV AH,00
MOV AL,Mode
INT 10h
ENDM
Pixel MACRO X,Y,Warna
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV AH,12 ; Servis menggambar kode pixel
MOV CX,X ; Posisi kolom atau X
MOV DX,Y ; Posisi baris atau Y
MOV AL,Warna ; Atribut Pixel
INT 10h ; gambar kode pixel itu !
POP DX
POP CX
POP BX
POP AX
ENDM
Heli MACRO Gambar,Warna
LOCAL Ulang1,Ulang2,Ulang3,Nol
PUSH AX ;
PUSH BX ; Simpan semua register yang
PUSH CX ; dipakai
PUSH DX ;
SUB BX,BX ;
MOV CX,32 ; CX = banyaknya baris
Ulang1:
PUSH CX
MOV CX,2 ; CX = banyaknya Word satu baris
Ulang2:
PUSH CX
MOV CX,16 ; CX = Banyaknya bit pada 1 word
MOV AX,1000000000000000b
Ulang3:
PUSH AX
AND AX,Gambar[BX] ; Apakah bit gambar kode ke AX=1 ?
JZ Nol ; Tidak, lompat
Pixel PosX,PosY,Warna ; Ya, gambar kode pixel
Nol:
POP AX ;
SHR AX,1 ; Untuk men-test bit gambar kode
INC PosX ;
LOOP Ulang3 ; Ulangi test bit berikutnya
ADD BX,2 ; Untuk mengakses word berikutnya
POP CX ;
LOOP Ulang2 ; Ulangi test word berikutnya
INC PosY ; Tambah posisi Y
SUB PosX,32 ; Kembalikan posisi X mula-mula
POP CX ;
LOOP Ulang1 ; Test word pada baris berikutnya
SUB PosY,32 ; Kembalikan posisi Y mula-mula
POP DX ;
POP CX ; Ambil kembali semua nilai
POP BX ; register yang disimpan
POP AX ;
ENDM
;/====================/;
.MODEL SMALL
.CODE
ORG 100h
TData : JMP Proses
Heli1 DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000001110000000b
DW 0000000000000000b,0000000100000000b
DW 0000000011111111b,1111111111111110b
DW 0000000000000000b,0000000100000000b
DW 0000000000000000b,0111111111000000b
DW 1110000000000000b,1111111111100000b
DW 0100000000111111b,1111000100110000b
DW 0111111111111111b,1111000100011000b
DW 0000000000000011b,1111000111111000b
DW 0000000000000000b,0111111111100000b
DW 0000000000000000b,0010000100001000b
DW 0000000000111111b,1111111111110000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
PosX DW 00 ; Posisi awal X
PosY DW 50 ; Posisi awal Y
Proses:
SetCRT 13h ; Aktifkan mode video grafik
MOV CX,0
Ulang:
Heli Heli1,50 ; gambar kode heli dengan warna 50
Delay ;
Heli Heli1,00 ; Hapus heli dengan warna hitam
INC PosX ; Tambah posisi X
INC CX ;
CMP CX,290 ; Ulangi sebanyak 290 kali
JE Exit ;
JMP Ulang ;
Exit:
SetCRT 03h ; Kemabli ke mode video default dos
INT 20h
END TData
program 25.6. Animasi Helikopter yang sedang terbang
Bila program 25.6. dieksekusi, maka pada layar akan ditampilkan sebuah
gambar kode helikopter (gambar kode 25.6) yang akan terbang melintasi monitor kita .
Pada bagian ini, akan pelajar lihat teknik lain dalam pembuatan suatu
animasi. Seperti yang sudah kita ketahui, dalam suatu modus mungkin saja
ada beberapa halaman layar. Halaman layar ini bisa pelajar manfaatkan untuk
pembuatan suatu animasi.
Untuk itu, gambarlah bentuk gambar kode yang diinginkan pada masing-masing
halaman layar. Sesudah itu kita tinggal mengaktifkan halaman layar untuk
memperoleh suatu efek gerakan.
Readkey MACRO ; Macro untuk menuggu
PUSH AX ; penekanan tombol keyboard
MOV AH,00
INT 16h
POP AX
ENDM
Ak_Page MACRO No ; Macro ini dipakai untuk
MOV AH,5 ; mengaktifkan halaman layar
MOV AL,No
INT 10h
ENDM
SetCRT MACRO Mode ; Macro untuk mengganti mode layar
MOV AH,00
MOV AL,Mode
INT 10h
ENDM
Pixel MACRO X,Y,Warna,Hlm
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV AH,12 ; Servis menggambar kode pixel
MOV CX,X ; Posisi kolom atau X
MOV DX,Y ; Posisi baris atau Y
MOV AL,Warna ; Atribut Pixel
MOV BH,Hlm ; Halaman layar
INT 10h ; gambar kode pixel itu !
POP DX
POP CX
POP BX
POP AX
ENDM
Hallo MACRO Gambar,Warna,Hlm
LOCAL Ulang1,Ulang2,Ulang3,Nol
PUSH AX ;
PUSH BX ; Simpan semua register yang
PUSH CX ; dipakai
PUSH DX ;
SUB BX,BX ;
MOV CX,32 ; CX = banyaknya baris
Ulang1:
PUSH CX
MOV CX,2 ; CX = banyaknya Word satu baris
Ulang2:
PUSH CX
MOV CX,16 ; CX = Banyaknya bit pada 1 word
MOV AX,1000000000000000b
Ulang3:
PUSH AX
AND AX,Gambar[BX] ; Apakah bit gambar kode ke AX=1 ?
JZ Nol ; Tidak, lompat
Pixel PosX,PosY,Warna,Hlm ; Ya, gambar kode pixel
Nol:
POP AX ;
SHR AX,1 ; Untuk men-test bit gambar kode
INC PosX ;
LOOP Ulang3 ; Ulangi test bit berikutnya
ADD BX,2 ; Untuk mengakses word berikutnya
POP CX ;
LOOP Ulang2 ; Ulangi test word berikutnya
INC PosY ; Tambah posisi Y
SUB PosX,32 ; Kembalikan posisi X mula-mula
POP CX ;
LOOP Ulang1 ; Test word pada baris berikutnya
SUB PosY,32 ; Kembalikan posisi Y mula-mula
POP DX ;
POP CX ; Ambil kembali semua nilai
POP BX ; register yang disimpan
POP AX ;
ENDM
;/=========================/;
.MODEL SMALL
.CODE
ORG 100h
TData : JMP Proses
Hall1 DW 0000000000000001b,1000000000000000b
DW 0000000000000011b,1000000000000000b
DW 0000000000000110b,0000000000000000b
DW 0000000000000111b,1000000000000000b
DW 0000000001111100b,1111110000000000b
DW 0000000110000100b,1000001100000000b
DW 0000001000001000b,0100000010000000b
DW 0000010000100000b,0011000001100000b
DW 0000100000100000b,0000100000010000b
DW 0001000000000000b,0000000000001000b
DW 0010000110000000b,0000000011000100b
DW 0100001111000000b,0000011111000100b
DW 0100000111100000b,0000011110000010b
DW 0100000110111000b,0001101100000010b
DW 0100000001111110b,0011111000000001b
DW 0100000000000000b,0000000000000001b
DW 0100000000000001b,1000000000000010b
DW 0100000000000011b,1100000000000010b
DW 0100000000000010b,1100000000000010b
DW 0010000100000000b,0000000010000010b
DW 0010000111000000b,0000001110000010b
DW 0010000011111100b,1100111100000100b
DW 0001000011111100b,1100111100000100b
DW 0001000001111111b,1111111000000100b
(186)
DW 0000100000011111b,1111100000001000b
DW 0000010000000111b,1110000000010000b
DW 0000001000000000b,0000000001100000b
DW 0000000110000000b,0000001110000000b
DW 0000000001110000b,1000010000000000b
DW 0000000000001111b,0111100000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
Hall2 DW 0000000000000011b,0000000000000000b
DW 0000000000000111b,0000000000000000b
DW 0000000000000110b,0000000000000000b
DW 0000000000000111b,1000000000000000b
DW 0000000001111100b,1111110000000000b
DW 0000000110000100b,1000001100000000b
DW 0000001000001000b,0100000010000000b
DW 0000010000100000b,0011000001100000b
DW 0000100000100000b,0000100000010000b
DW 0001000000000000b,0000000000001000b
DW 0010000100000000b,0000000010000100b
DW 0100001110000000b,0000011100000100b
DW 0100000111000000b,0000011100000010b
DW 0100000111100000b,0001111000000010b
DW 0100000001111000b,0011100000000001b
DW 0100000000000000b,0000000000000001b
DW 0100000000000001b,1000000000000010b
DW 0100000000000011b,1100000000000010b
DW 0100000000000010b,1100000000000010b
DW 0010000000000000b,0000000000000010b
DW 0010000000000000b,0000000000000010b
DW 0010000010000000b,0000000100000100b
DW 0001000011100000b,0000111100000100b
DW 0001000001111101b,1111111000000100b
DW 0000100000011111b,1111100000001000b
DW 0000010000000111b,1110000000010000b
DW 0000001000000000b,0000000001100000b
DW 0000000110000000b,0000001110000000b
DW 0000000001110000b,1000010000000000b
DW 0000000000001111b,0111100000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
Hall3 DW 0000000000111100b,0000000000000000b
DW 0000000000001111b,0000000000000000b
DW 0000000000000110b,0000000000000000b
DW 0000000000000111b,1000000000000000b
DW 0000000001111100b,1111110000000000b
DW 0000000110000100b,1000001100000000b
DW 0000001000001000b,0100000010000000b
DW 0000010000100000b,0011000001100000b
DW 0000100000100000b,0000100000010000b
DW 0001000000000000b,0000000000001000b
DW 0010000000000000b,0000000000000100b
DW 0100000000000000b,0000001100000100b
DW 0100000100000000b,0000011000000010b
DW 0100000111000000b,0000110000000010b
DW 0100000001111100b,0001100000000001b
DW 0100000000000000b,0000000000000001b
DW 0100000000000001b,1000000000000010b
DW 0100000000000011b,1100000000000010b
DW 0100000000000010b,1100000000000010b
DW 0010000000000000b,0000000000000010b
DW 0010000000000000b,0000000000000010b
DW 0010000011000000b,0000001000000100b
DW 0001000011111000b,0100111000000100b
DW 0001000000011100b,0111111000000100b
DW 0000100000001111b,1111100000001000b
DW 0000010000000000b,0000000000010000b
DW 0000001000000000b,0000000001100000b
DW 0000000110000000b,0000001110000000b
DW 0000000001110000b,1000010000000000b
DW 0000000000001111b,0111100000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
Hall4 DW 0000000001110000b,0000000000000000b
DW 0000000011011110b,0000000000000000b
DW 0000000000000111b,0000000000000000b
DW 0000000000000111b,1000000000000000b
DW 0000000001111100b,1111110000000000b
DW 0000000110000100b,1000001100000000b
DW 0000001000001000b,0100000010000000b
DW 0000010000100000b,0011000001100000b
DW 0000100000100000b,0000100000010000b
DW 0001000000000000b,0000000000001000b
DW 0010000000000000b,0000000000000100b
DW 0100000000000000b,0000000000000100b
DW 0100000000000000b,0000000000000010b
DW 0100000000000000b,0000000000000010b
DW 0100000000000000b,0000000000000001b
DW 0100000000000000b,0000000000000001b
DW 0100000000000001b,1000000000000010b
DW 0100000000000011b,1100000000000010b
DW 0100000000000010b,1100000000000010b
DW 0010000000000000b,0000000000000010b
DW 0010000000000000b,0000000000000010b
DW 0010000000000000b,0000000000000100b
DW 0001000000000000b,0000000000000100b
DW 0001000000000000b,0000000000000100b
DW 0000100000000000b,1000000000001000b
DW 0000010000000100b,0010000000010000b
DW 0000001000000011b,1100000001100000b
DW 0000000110000000b,0000001110000000b
DW 0000000001110000b,1000010000000000b
DW 0000000000001111b,0111100000000000b
DW 0000000000000000b,0000000000000000b
DW 0000000000000000b,0000000000000000b
PosX DW 150 ; Posisi awal X
PosY DW 70 ; Posisi awal Y
Proses:
SetCRT 13 ; Aktifkan mode video grafik
Hallo Hall1,20,0 ; gambar kode hall1 pada halaman 0
Hallo Hall2,21,1 ; gambar kode hall2 pada halaman 1
Hallo Hall3,22,2 ; gambar kode hall3 pada halaman 2
Hallo Hall4,23,3 ; gambar kode hall4 pada halaman 3
MOV AL,4
Ulang1:
DEC AL
Ak_Page AL ; Aktifkan halaman layar ke AL
Readkey
CMP AL,0
JNE Ulang1
Exit:
SetCRT 03h ; Kemabli ke mode video default dos
INT 20h
END TData
program 25.7. Animasi dengan halaman layar
Bila program 25.7. dieksekusi, maka pada layar akan ditampilkan gambar
pumpkin yang akan berubah mimik wajahnya setiap ditekan sembarang
tombol(gambar kode 25.6).
<<<<< Gbr257.PIX >>>>>
gambar kode 25.7. Hasil eksekusi program 25.7.
Pada awal program pelajar mangaktifkan modus grafik 13 yang memiliki
halaman tampilan sebanyak 4 buah(0, 1, 2 dan 3). sebab modus yang dipakai
memiliki halaman tampilan lebih dari satu, maka pada macro yang menggambar
Pixel, ditambahkan register BH yang berisi nomor halaman yang akan digambari
pixel.