0
0
Fork 0
mirror of https://git.sr.ht/~rabbits/uxn synced 2024-11-30 01:33:01 +00:00

Migrated loops to relative format

This commit is contained in:
neauoire 2021-03-11 14:00:32 -08:00
parent 9bb4b84e2f
commit 59e6ced7b9
5 changed files with 67 additions and 59 deletions

View file

@ -24,19 +24,30 @@ evaluxn(u, u->vframe); /* Each frame
## Assembly Syntax ## Assembly Syntax
- `ADD`, an opcode. ### Define
- `@label`, assign the current address to a label. - `@label`, assign the current address to a label.
- `;variable 2`, assign an address to a label automatically. - `;variable 2`, assign an address to a label automatically.
- `:const 1a2b`, assign an address to a label manually. - `:const 1a2b`, assign an address to a label manually.
- `&macro { x 2 y 2 }`, define a macro named `macro`. - `&macro { x 2 y 2 }`, define a macro named `macro`.
### Program
- `ADD`, push an opcode.
- `.address`, push label address to memory. - `.address`, push label address to memory.
- `,literal`, push label address to stack, prefixed with `LIT LEN`. - `,literal`, push label address to stack, prefixed with `LIT LEN`.
- `#1a`, a literal byte/short. - `#1a`, push a literal byte/short.
- `+1a`, a literal signed byte/short. - `+1a`, push a literal signed byte/short.
- `-1a`, a literal signed byte/short(negative). - `-1a`, push a literal signed byte/short(negative).
- `|0010`, move to position in the program.
### Helpers
- `=label`, helper to STR, equivalent to `,label STR`, or `label STR2`. - `=label`, helper to STR, equivalent to `,label STR`, or `label STR2`.
- `~label`, helper to LDR, equivalent to `,label LDR2`, or `,label LDR2`. - `~label`, helper to LDR, equivalent to `,label LDR2`, or `,label LDR2`.
- `|0010`, move to position in the program.
### Blocks
- `( comment )`, toggle parsing on/off. - `( comment )`, toggle parsing on/off.
- `[ 0123 abcd ]`, write shorts to memory. - `[ 0123 abcd ]`, write shorts to memory.
- `[ Hello World ]`, write text to memory. - `[ Hello World ]`, write text to memory.
@ -64,15 +75,15 @@ BRK
@print-label ( text ) @print-label ( text )
@print-label-loop NOP NOP
( send ) DUP2 LDR =CNSL.char ( send ) DUP2 LDR =CNSL.char
( incr ) #0001 ADD2 ( incr ) #0001 ADD2
DUP2 LDR #00 NEQ ^print-label-loop MUL JMPS ( loop ) DUP2 LDR #00 NEQ ^print-label MUL JMPS
POP2 POP2
RTS RTS
@text1 [ Hello 20 World 0a00 ] ( store text with a linebreak and null byte ) @text1 [ Hello 20 World 0a00 ] ( text with linebreak and null bytes )
@text2 [ Welcome 20 to 20 UxnVM 0a00 ] @text2 [ Welcome 20 to 20 UxnVM 0a00 ]
|c000 @FRAME |c000 @FRAME
@ -95,14 +106,9 @@ RTS
- Includes - Includes
- Defines - Defines
- Jump relative
- Local loops - Local loops
- Jump helpers - Jump helpers
NOTE: OPCODES should not be relative, but there should be a relative accessor for addresses, like:
$relative_name JMP
## Notes ## Notes
### Conditional Jumping ### Conditional Jumping

View file

@ -308,6 +308,8 @@ pass1(FILE *f)
break; break;
case '=': addr += 4; break; /* STR helper (lit addr-hb addr-lb str) */ case '=': addr += 4; break; /* STR helper (lit addr-hb addr-lb str) */
case '~': addr += 4; break; /* LDR helper (lit addr-hb addr-lb ldr) */ case '~': addr += 4; break; /* LDR helper (lit addr-hb addr-lb ldr) */
case '$': addr += 4; break; /* JSR helper (lit addr-hb addr-lb jsr) */
case '/': addr += 4; break; /* JMP helper (lit addr-hb addr-lb jmp) */
case ',': addr += 3; break; case ',': addr += 3; break;
case '.': addr += 2; break; case '.': addr += 2; break;
case '^': addr += 2; break; /* Relative jump: lit addr-offset */ case '^': addr += 2; break; /* Relative jump: lit addr-offset */
@ -347,15 +349,16 @@ pass2(FILE *f)
else if(w[0] == '^' && (l = findlabel(w + 1))) { else if(w[0] == '^' && (l = findlabel(w + 1))) {
int off = l->addr - p.ptr - 3; int off = l->addr - p.ptr - 3;
if(off < -126 || off > 126){ printf("Address %s is too far(%d).\n", w, off); return 0; } if(off < -126 || off > 126){ printf("Address %s is too far(%d).\n", w, off); return 0; }
printf("relative %s[%d]\n", w, l->addr - p.ptr - 4);
pushbyte((Sint8)(l->addr - p.ptr - 3), 1); l->refs++; pushbyte((Sint8)(l->addr - p.ptr - 3), 1); l->refs++;
} }
else if(w[0] == ':') fscanf(f, "%s", w); else if(w[0] == ':') fscanf(f, "%s", w);
else if(w[0] == ';') fscanf(f, "%s", w); else if(w[0] == ';') fscanf(f, "%s", w);
else if(w[0] == '.' && (l = findlabel(w + 1))) { pushshort(findlabeladdr(w + 1), 0); l->refs++; } else if(w[0] == '.' && (l = findlabel(w + 1))) { pushshort(findlabeladdr(w + 1), 0); l->refs++; }
else if(w[0] == ',' && (l = findlabel(w + 1))) { pushshort(findlabeladdr(w + 1), 1); l->refs++; } else if(w[0] == ',' && (l = findlabel(w + 1))) { pushshort(findlabeladdr(w + 1), 1); l->refs++; }
else if(w[0] == '=' && (l = findlabel(w + 1)) && l->len){ pushshort(findlabeladdr(w + 1), 1); pushbyte(findopcode(findlabellen(w+1) == 2 ? "STR2" : "STR"), 0); l->refs++;} else if(w[0] == '=' && (l = findlabel(w + 1)) && l->len){ pushshort(findlabeladdr(w + 1), 1); pushbyte(findopcode(findlabellen(w + 1) == 2 ? "STR2" : "STR"), 0); l->refs++;}
else if(w[0] == '~' && (l = findlabel(w + 1)) && l->len){ pushshort(findlabeladdr(w + 1), 1); pushbyte(findopcode(findlabellen(w+1) == 2 ? "LDR2" : "LDR"), 0); l->refs++;} else if(w[0] == '~' && (l = findlabel(w + 1)) && l->len){ pushshort(findlabeladdr(w + 1), 1); pushbyte(findopcode(findlabellen(w + 1) == 2 ? "LDR2" : "LDR"), 0); l->refs++;}
else if(w[0] == '/' && (l = findlabel(w + 1))){ pushshort(findlabeladdr(w + 1), 1); pushbyte(findopcode("JMP2"), 0); l->refs++;}
else if(w[0] == '$' && (l = findlabel(w + 1))){ pushshort(findlabeladdr(w + 1), 1); pushbyte(findopcode("JSR2"), 0); l->refs++;}
else if(w[0] == '#' && sihx(w + 1) && slen(w + 1) == 2) pushbyte(shex(w + 1), 1); else if(w[0] == '#' && sihx(w + 1) && slen(w + 1) == 2) pushbyte(shex(w + 1), 1);
else if(w[0] == '#' && sihx(w + 1) && slen(w + 1) == 4) pushshort(shex(w + 1), 1); else if(w[0] == '#' && sihx(w + 1) && slen(w + 1) == 4) pushshort(shex(w + 1), 1);
else if(w[0] == '+' && sihx(w + 1) && slen(w + 1) == 2) pushbyte((Sint8)shex(w + 1), 1); else if(w[0] == '+' && sihx(w + 1) && slen(w + 1) == 2) pushbyte((Sint8)shex(w + 1), 1);

View file

@ -4,8 +4,8 @@
|0100 @RESET |0100 @RESET
,text1 ,print-label JSR2 ,text1 $print-label
,text2 ,print-label JSR2 ,text2 $print-label
#ab =CNSL.byte #ab =CNSL.byte
#cdef =CNSL.short #cdef =CNSL.short
@ -16,13 +16,15 @@ BRK
@print-label-loop NOP @print-label-loop NOP
( send ) DUP2 LDR =CNSL.char ( send ) DUP2 LDR =CNSL.char
( incr ) #0001 ADD2 ( incr ) #0001 ADD2
DUP2 LDR #00 NEQ ^print-label-loop MUL JMPS ( loop ) DUP2 LDR #00 NEQ ^print-label-loop MUL JMPS
POP2 POP2
RTS RTS
@text1 [ Hello 20 World 0a00 ] ( store text with a linebreak and null byte ) ( store text in memory )
@text2 [ Welcome 20 to 20 UxnVM 0a00 ]
@text1 [ Welcome 20 to 20 UxnVM 0a00 ]
@text2 [ Hello 20 World 0a00 ]
|c000 @FRAME |c000 @FRAME
|d000 @ERROR |d000 @ERROR

View file

@ -211,9 +211,9 @@ RTS
( get file length ) ( get file length )
,document.body =document.eof ,document.body =document.eof
@load-file-loop @load-file-loop NOP
( incr ) ~document.eof #0001 ADD2 =document.eof ( incr ) ~document.eof #0001 ADD2 =document.eof
,load-file-loop ~document.eof LDR #00 NEQ JMP2? POP2 ~document.eof LDR #00 NEQ ^load-file-loop MUL JMPS
RTS RTS
@ -221,10 +221,10 @@ RTS
=i =i
~selection.from #0001 SUB2 =j ( start -> end ) ~selection.from #0001 SUB2 =j ( start -> end )
@shift-left-loop @shift-left-loop NOP
( move ) ~j ~i ADD2 LDR ~j STR ( move ) ~j ~i ADD2 LDR ~j STR
( incr ) ~j #0001 ADD2 =j ( incr ) ~j #0001 ADD2 =j
,shift-left-loop ~j ~document.eof LTH2 JMP2? POP2 ~j ~document.eof LTH2 ^shift-left-loop MUL JMPS
~document.eof ~i SUB2 =document.eof ~document.eof ~i SUB2 =document.eof
RTS RTS
@ -233,10 +233,10 @@ RTS
=i =i
~document.eof =j ( end -> start ) ~document.eof =j ( end -> start )
@shift-right-loop @shift-right-loop NOP
( move ) ~j ~i SUB2 LDR ~j STR ( move ) ~j ~i SUB2 LDR ~j STR
( decr ) ~j #0001 SUB2 =j ( decr ) ~j #0001 SUB2 =j
,shift-right-loop ~j ~selection.from GTH2 JMP2? POP2 ~j ~selection.from GTH2 ^shift-right-loop MUL JMPS
~document.eof ~i ADD2 =document.eof ~document.eof ~i ADD2 =document.eof
RTS RTS
@ -250,11 +250,11 @@ RTS
@goto-linestart @goto-linestart
@goto-linestart-loop @goto-linestart-loop NOP
~selection.from #0001 SUB2 LDR #0a EQU RTS? ~selection.from #0001 SUB2 LDR #0a EQU RTS?
~selection.from #0001 SUB2 LDR #0d EQU RTS? ~selection.from #0001 SUB2 LDR #0d EQU RTS?
( decr ) ~selection.from DUP2 =selection.to #0001 SUB2 =selection.from ( decr ) ~selection.from DUP2 =selection.to #0001 SUB2 =selection.from
,goto-linestart-loop ~selection.from LDR #00 NEQ JMP2? POP2 ~selection.from LDR #00 NEQ ^goto-linestart-loop MUL JMPS
( clamp at document body ) ( clamp at document body )
~selection.from ,document.body GTH2 RTS? ~selection.from ,document.body GTH2 RTS?
,document.body DUP2 =selection.from #0001 ADD2 =selection.to ,document.body DUP2 =selection.from #0001 ADD2 =selection.to
@ -263,11 +263,11 @@ RTS
@goto-lineend @goto-lineend
@goto-lineend-loop @goto-lineend-loop NOP
~selection.from LDR #0a EQU RTS? ~selection.from LDR #0a EQU RTS?
~selection.from LDR #0d EQU RTS? ~selection.from LDR #0d EQU RTS?
( incr ) ~selection.from #0001 ADD2 DUP2 #0001 ADD2 =selection.to =selection.from ( incr ) ~selection.from #0001 ADD2 DUP2 #0001 ADD2 =selection.to =selection.from
,goto-lineend-loop ~selection.from LDR #00 NEQ JMP2? POP2 ~selection.from LDR #00 NEQ ^goto-lineend-loop MUL JMPS
( clamp at document body ) ( clamp at document body )
~selection.from ,document.eof LTH2 RTS? ~selection.from ,document.eof LTH2 RTS?
,document.eof #0001 SUB2 DUP2 =selection.from #0001 ADD2 =selection.to ,document.eof #0001 SUB2 DUP2 =selection.from #0001 ADD2 =selection.to
@ -277,12 +277,12 @@ RTS
@find-wordstart @find-wordstart
~selection.to =j ~selection.to =j
@find-wordstart-loop @find-wordstart-loop NOP
( decr ) ~j #0001 SUB2 =j ( decr ) ~j #0001 SUB2 =j
,find-wordstart-end ~j LDR #20 EQU JMP2? POP2 ,find-wordstart-end ~j LDR #20 EQU JMP2? POP2
,find-wordstart-end ~j LDR #0a EQU JMP2? POP2 ,find-wordstart-end ~j LDR #0a EQU JMP2? POP2
,find-wordstart-end ~j LDR #0d EQU JMP2? POP2 ,find-wordstart-end ~j LDR #0d EQU JMP2? POP2
,find-wordstart-loop ~j ,document.body GTH2 JMP2? POP2 ~j ,document.body GTH2 ^find-wordstart-loop MUL JMPS
@find-wordstart-end @find-wordstart-end
( return ) ~j #0001 SUB2 ( return ) ~j #0001 SUB2
@ -291,12 +291,12 @@ RTS
@find-wordend @find-wordend
~selection.to =j ~selection.to =j
@find-wordend-loop @find-wordend-loop NOP
( incr ) ~j #0001 ADD2 =j ( incr ) ~j #0001 ADD2 =j
,find-wordend-end ~j LDR #20 EQU JMP2? POP2 ,find-wordend-end ~j LDR #20 EQU JMP2? POP2
,find-wordend-end ~j LDR #0a EQU JMP2? POP2 ,find-wordend-end ~j LDR #0a EQU JMP2? POP2
,find-wordend-end ~j LDR #0d EQU JMP2? POP2 ,find-wordend-end ~j LDR #0d EQU JMP2? POP2
,find-wordend-loop ~j ,document.body GTH2 JMP2? POP2 ~j ,document.body GTH2 ^find-wordend-loop MUL JMPS
@find-wordend-end @find-wordend-end
( return ) ~j #0001 ADD2 ( return ) ~j #0001 ADD2
@ -305,11 +305,11 @@ RTS
@find-lineoffset ( return character offset from linestart ) @find-lineoffset ( return character offset from linestart )
#0000 =j #0000 =j
@find-lineoffset-loop @find-lineoffset-loop NOP
( incr ) ~j #0001 ADD2 =j ( incr ) ~j #0001 ADD2 =j
,find-lineoffset-end ~selection.from ~j SUB2 LDR #0a EQU JMP2? POP2 ,find-lineoffset-end ~selection.from ~j SUB2 LDR #0a EQU JMP2? POP2
,find-lineoffset-end ~selection.from ~j SUB2 LDR #0d EQU JMP2? POP2 ,find-lineoffset-end ~selection.from ~j SUB2 LDR #0d EQU JMP2? POP2
,find-lineoffset-loop ~selection.from ~j SUB2 ,document.body GTH2 JMP2? POP2 ~selection.from ~j SUB2 ,document.body GTH2 ^find-lineoffset-loop MUL JMPS
@find-lineoffset-end @find-lineoffset-end
( return ) ~j ( return ) ~j
@ -318,13 +318,13 @@ RTS
@find-line ( position -> addr ) @find-line ( position -> addr )
,document.body =j #0000 =pt.y ,document.body =j #0000 =pt.y
@find-line-loop @find-line-loop NOP
,find-line-end ~pt.y ~position.y #0001 SUB2 GTH2 JMP2? POP2 ,find-line-end ~pt.y ~position.y #0001 SUB2 GTH2 JMP2? POP2
,find-line-no-space ~j LDR #0a NEQ ~j LDR #0d NEQ #0101 EQU2 JMP2? POP2 ,find-line-no-space ~j LDR #0a NEQ ~j LDR #0d NEQ #0101 EQU2 JMP2? POP2
( incr ) ~pt.y #0001 ADD2 =pt.y ( incr ) ~pt.y #0001 ADD2 =pt.y
@find-line-no-space @find-line-no-space
( incr ) ~j #0001 ADD2 =j ( incr ) ~j #0001 ADD2 =j
,find-line-loop ~j LDR #00 NEQ JMP2? POP2 ~j LDR #00 NEQ ^find-line-loop MUL JMPS
@find-line-end @find-line-end
( return ) ~j ( return ) ~j
@ -336,11 +336,11 @@ RTS
#0000 =pt.x #0000 =pt.x
@find-selection-loop @find-selection-loop NOP
,find-selection-end ~j ~pt.x ADD2 LDR #0a EQU JMP2? POP2 ,find-selection-end ~j ~pt.x ADD2 LDR #0a EQU JMP2? POP2
,find-selection-end ~j ~pt.x ADD2 LDR #0d EQU JMP2? POP2 ,find-selection-end ~j ~pt.x ADD2 LDR #0d EQU JMP2? POP2
( incr ) ~pt.x #0001 ADD2 =pt.x ( incr ) ~pt.x #0001 ADD2 =pt.x
,find-selection-loop ~pt.x ~position.x #0001 SUB2 LTH2 JMP2? POP2 ~pt.x ~position.x #0001 SUB2 LTH2 ^find-selection-loop MUL JMPS
@find-selection-end @find-selection-end
( return ) ~pt.x ADD2 ( return ) ~pt.x ADD2
@ -351,17 +351,14 @@ RTS
,document.body =selection.from #0000 =pt.x #0000 =pt.y ,document.body =selection.from #0000 =pt.x #0000 =pt.y
@select-loop @select-loop
,no-space ~selection.from LDR #0a NEQ ~selection.from LDR #0d NEQ #0101 EQU2 JMP2? POP2 ,no-space ~selection.from LDR #0a NEQ ~selection.from LDR #0d NEQ #0101 EQU2 JMP2? POP2
( incr ) ~pt.y #0001 ADD2 =pt.y ( incr ) ~pt.y #0001 ADD2 =pt.y
#0000 =pt.x #0000 =pt.x
@no-space @no-space
,no-reached ~pt.y ~position.y #0001 SUB2 GTH2 ~pt.x ~position.x #0001 SUB2 GTH2 #0101 NEQ2 JMP2? POP2 ,no-reached ~pt.y ~position.y #0001 SUB2 GTH2 ~pt.x ~position.x #0001 SUB2 GTH2 #0101 NEQ2 JMP2? POP2
~selection.from #0001 ADD2 =selection.to ~selection.from #0001 ADD2 =selection.to
RTS RTS
@no-reached @no-reached
( incr ) ~pt.x #0001 ADD2 =pt.x ( incr ) ~pt.x #0001 ADD2 =pt.x
( incr ) ~selection.from #0001 ADD2 =selection.from ( incr ) ~selection.from #0001 ADD2 =selection.from
,select-loop ~selection.from LDR #00 NEQ JMP2? POP2 ,select-loop ~selection.from LDR #00 NEQ JMP2? POP2
@ -457,13 +454,13 @@ RTS
( scroll to position ) ( scroll to position )
#0000 =j ( j is linebreaks ) #0000 =j ( j is linebreaks )
@find-scroll-offset @find-scroll-offset NOP
,find-scroll-offset-end ~scroll.y ~j EQU2 JMP2? POP2 ,find-scroll-offset-end ~scroll.y ~j EQU2 JMP2? POP2
,no-break ~textarea.addr LDR #0a NEQ ~textarea.addr LDR #0d NEQ #0101 EQU2 JMP2? POP2 ,no-break ~textarea.addr LDR #0a NEQ ~textarea.addr LDR #0d NEQ #0101 EQU2 JMP2? POP2
( incr ) ~j #0001 ADD2 =j ( incr ) ~j #0001 ADD2 =j
@no-break @no-break
( incr ) ~textarea.addr #0001 ADD2 =textarea.addr ( incr ) ~textarea.addr #0001 ADD2 =textarea.addr
,find-scroll-offset ~textarea.addr LDR #00 NEQ JMP2? POP2 ~textarea.addr LDR #00 NEQ ^find-scroll-offset MUL JMPS
@find-scroll-offset-end @find-scroll-offset-end
~textarea.addr #0000 ADD2 =textarea.addr ~textarea.addr #0000 ADD2 =textarea.addr
@ -542,11 +539,11 @@ RTS
( load ) =label.addr =label.color =SPRT.y =SPRT.x ( load ) =label.addr =label.color =SPRT.y =SPRT.x
~label.addr ~label.addr
@draw-titlebar-loop @draw-titlebar-loop NOP
( draw ) DUP2 LDR #00 SWP #20 SUB #0008 MUL2 ,font ADD2 =SPRT.addr ~label.color =SPRT.color ( draw ) DUP2 LDR #00 SWP #20 SUB #0008 MUL2 ,font ADD2 =SPRT.addr ~label.color =SPRT.color
( incr ) #0001 ADD2 ( incr ) #0001 ADD2
( incr ) ~SPRT.x #0008 ADD2 =SPRT.x ( incr ) ~SPRT.x #0008 ADD2 =SPRT.x
DUP2 LDR #00 NEQ ,draw-titlebar-loop ROT JMP2? POP2 DUP2 LDR #00 NEQ ^draw-titlebar-loop MUL JMPS
POP2 POP2
( selection ) ( selection )

View file

@ -116,27 +116,27 @@ BRK
,not-copy-mode ~bankview.mode #01 NEQ JMP2? POP2 ,not-copy-mode ~bankview.mode #01 NEQ JMP2? POP2
#00 =i #00 =i
@copy-loop @copy-loop NOP
( load ) ~tileview.addr ~i ADD LDR ( load ) ~tileview.addr ~i ADD LDR
( get touch addr ) ( get touch addr )
~MOUS.x ~bankview.x SUB2 #0008 DIV2 #0008 MUL2 ~MOUS.x ~bankview.x SUB2 #0008 DIV2 #0008 MUL2
~MOUS.y ~bankview.y SUB2 #0008 DIV2 #0008 MUL2 #0010 MUL2 ADD2 ~MOUS.y ~bankview.y SUB2 #0008 DIV2 #0008 MUL2 #0010 MUL2 ADD2
~bankview.addr ADD2 #00 ~i ADD2 STR ~bankview.addr ADD2 #00 ~i ADD2 STR
( incr ) ~i #01 ADD =i ( incr ) ~i #01 ADD =i
,copy-loop ~i #08 LTH JMP2? POP2 ~i #08 LTH ^copy-loop MUL JMPS
,redraw JSR2 ,click-end JMP2 ,redraw JSR2 ,click-end JMP2
@not-copy-mode @not-copy-mode
,not-erase-mode ~bankview.mode #02 NEQ JMP2? POP2 ,not-erase-mode ~bankview.mode #02 NEQ JMP2? POP2
#00 =i #00 =i
@erase-loop @erase-loop NOP
#00 #00
( get touch addr ) ( get touch addr )
~MOUS.x ~bankview.x SUB2 #0008 DIV2 #0008 MUL2 ~MOUS.x ~bankview.x SUB2 #0008 DIV2 #0008 MUL2
~MOUS.y ~bankview.y SUB2 #0008 DIV2 #0008 MUL2 #0010 MUL2 ADD2 ~MOUS.y ~bankview.y SUB2 #0008 DIV2 #0008 MUL2 #0010 MUL2 ADD2
~bankview.addr ADD2 #00 ~i ADD2 STR ~bankview.addr ADD2 #00 ~i ADD2 STR
( incr ) ~i #01 ADD =i ( incr ) ~i #01 ADD =i
,erase-loop ~i #08 LTH JMP2? POP2 ~i #08 LTH ^erase-loop MUL JMPS
,redraw JSR2 ,click-end JMP2 ,redraw JSR2 ,click-end JMP2
@not-erase-mode @not-erase-mode
@ -470,17 +470,17 @@ RTS
@line-rect ( x1 y1 x2 y2 color ) @line-rect ( x1 y1 x2 y2 color )
( load ) =color =rect.y2 =rect.x2 DUP2 =SCRN.y =rect.y1 DUP2 =SCRN.x =rect.x1 ( load ) =color =rect.y2 =rect.x2 DUP2 =SCRN.y =rect.y1 DUP2 =SCRN.x =rect.x1
@line-rect-hor @line-rect-hor NOP
( incr ) ~SCRN.x #0001 ADD2 =SCRN.x ( incr ) ~SCRN.x #0001 ADD2 =SCRN.x
( draw ) ~rect.y1 =SCRN.y ~color =SCRN.color ( draw ) ~rect.y1 =SCRN.y ~color =SCRN.color
( draw ) ~rect.y2 =SCRN.y ~color =SCRN.color ( draw ) ~rect.y2 =SCRN.y ~color =SCRN.color
,line-rect-hor ~SCRN.x ~rect.x2 LTH2 JMP2? POP2 ~SCRN.x ~rect.x2 LTH2 ^line-rect-hor MUL JMPS
~rect.y1 =SCRN.y ~rect.y1 =SCRN.y
@line-rect-ver @line-rect-ver NOP
( draw ) ~rect.x1 =SCRN.x ~color =SCRN.color ( draw ) ~rect.x1 =SCRN.x ~color =SCRN.color
( draw ) ~rect.x2 =SCRN.x ~color =SCRN.color ( draw ) ~rect.x2 =SCRN.x ~color =SCRN.color
( incr ) ~SCRN.y #0001 ADD2 =SCRN.y ( incr ) ~SCRN.y #0001 ADD2 =SCRN.y
,line-rect-ver ~SCRN.y ~rect.y2 #0001 ADD2 LTH2 JMP2? POP2 ~SCRN.y ~rect.y2 #0001 ADD2 LTH2 ^line-rect-ver MUL JMPS
RTS RTS